2011-09-06 7 views
2

내 프로젝트에서 웹캠 ZoneTrigger를 intergrate하도록 요청 받았습니다. 사이트에서 제공되는 SDK는 C++ 샘플입니다. 몇 가지 기능을 사용할 수있었습니다. 내가 갇혀있는 곳은 char *가 전달 된 매개 변수 인 함수입니다. C#C++에서 관리되지 않는 DLL #

로 변환 할 때 나는

//header file 
struct ZT_TRIG_STRUCT 
{ 
int aSize;  //STRUCT size 
int CameraIndex; 
int SpotIndex; 
int SpotType; 
char SpotName[32]; 
DWORD Dummy[16]; 
}; 

typedef int (WINAPI *f_ZT_EnumerateHotSpots)(int SpotIndex, char *Name, int *SpotType); 
/* 
You application can call this functions to retrieve information about spots by iterating the SpotIndex param. 
Name is a pointer to a 32 byte buffer supplied by your application. 
SpotType is a pointer to an 32 bit integer in your application. 
Return value: 
0 = Success, the Name and SpotType have been initialized 
1 = Error, we have lost communication with Zone Trigger 
2 = Enumaration is over, all spots have been enumerated. Your application should increment SpotIndex until this function returns 2. 
*/ 

//code 
//Enumerate current spots in Zone Trigger 
int i=0; 
char SpotName[32]; 
int SpotType; 
check = ZT_EnumerateHotSpots(i, SpotName, &SpotType); 
while (check == 0) 
{ 
    float sensitivity = ZT_GetSensitivity(i); 
    printf("Zone Trigger spot: %s Sensitivity: %0.1f%%\r\n", SpotName,  sensitivity*100); 
    check = ZT_EnumerateHotSpots(++i, SpotName, &SpotType); 
} 

그래서 ++ 코드

내가 C에서 가져올하고자하는 기능 ... 파고를 많이했고, MarshalAs를 사용한다는 것을 알게했다

[DllImport("ZTcom.dll")] 
    private static extern int ZT_EnumerateHotSpots(int i, [MarshalAs(UnmanagedType.LPWStr)]ref string SpotName, ref int SpotType); 

public unsafe struct ZT_TRIG_STRUCT 
    { 
     public int aSize;  //STRUCT size 
     public int CameraIndex; 
     public int SpotIndex; 
     public int SpotType; 
     public string SpotName ; 
     //[MarshalAs(UnmanagedType.LPStr, SizeConst = 256)] string SpotName; 
     // public IntPtr SpotName; 
    } 

//In code 
int i = 0; 
string SpotName; 
int SpotType; 
check = ZT_EnumerateHotSpots(i, ref SpotName, ref SpotType); 

상기 라인 준다 :

Exception of type 'System.ExecutionEngineException' was thrown. 

오류.

SpotName에 해당 문제가 있다는 것을 알고 있습니다. marshalAs를 사용하지 않으면, 대신에 char가 사용됩니다. n은 첫 번째 char을 나타냅니다. 코드가 올바르게 작동합니다. 문자는

public unsafe struct ZT_TRIG_STRUCT 
    { 
     public int aSize;  //STRUCT size 
     public int CameraIndex; 
     public int SpotIndex; 
     public int SpotType; 
     public char SpotName ;    
    } 

[DllImport("ZTcom.dll")] 
    private static extern int ZT_EnumerateHotSpots(int i, ref char SpotName, ref int SpotType); 

public char SpotName; 
int i = 0; 
      check = ZT_EnumerateHotSpots(i, ref SpotName, ref SpotType); 
      while (check == 0) 
      { 
       float sensitivity = ZT_GetSensitivity(i); 
       textBox1.Text = textBox1.Text + "\r\n" +"Zone Trigger spot: " + SpotName + " Sensitivity: " + (sensitivity * 100).ToString(); 
       check = ZT_EnumerateHotSpots(++i, ref SpotName, ref SpotType); 
      } 

이하하지만 난 숯불 넣을 경우 [] 내가 잘못 갔다 내가 여기에 옵션이 부족했습니다

Method's type signature is not Interop compatible. ERROR 

을 .... 준다? MarshalAs 또는 char [] ??? 사용해야합니까? 당신이 ZT_TRIG_STRUCT를 사용하는 경우

+0

처럼이 전화를? 안전하지 않은 멤버가 없습니다. – Sven

+0

[MarshalAs (UnmanagedType.LPStr, SizeConst = 32)] 문자열 SpotName; 작동하지 않습니까? –

+0

@Preet 인라인 문자열은'LPStr'가 아닌'UnmanagedType.ByValTStr'을 사용해야합니다; 내 대답을 보라. – Sven

답변

4

내가 볼 수 없습니다 .... 사전에 ..... 덕분에 도움이되지만 그것은 다음과 같이 선언해야 바랍니다 :

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] 
public struct ZT_TRIG_STRUCT 
{ 
    public int aSize; 
    public int CameraIndex; 
    public int SpotIndex; 
    public int SpotType; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] 
    public string SpotName; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=16)] 
    public uint[] Dummy; 
} 

다른 문제를 have는 ZT_EnumerateHotSpots의 선언에 있습니다. 즉되어야한다 : 나는 그것을 읽으면서, SpotName 실제로 out 매개 변수입니다

[DllImport("ZTcom.dll", CharSet=CharSet.Ansi)] 
private static extern int ZT_EnumerateHotSpots(
    int SpotIndex, 
    StringBuilder SpotName, 
    out int SpotType 
); 

, 즉 당신은 버퍼를 제공하고 ZT_EnumerateHotSpots은 기록합니다.

그런 다음`ZT_TRIG_STRUCT`가 안전하지 않은 표시됩니다 왜 그렇게

int SpotIndex = 0; 
StringBuilder SpotName = new StringBuilder(32); 
int SpotType; 
int result = ZT_EnumerateHotSpots(SpotIndex, SpotName, out SpotType); 
+0

그래, 이름이 Out 매개 변수가되고 StringBuilder가 필요합니다. 나는 그 말을하지 않았다, 말장난 의도). 나는 내 대답을 지우고 너를 상향시켰다. – Sven

+0

@Sven Thanks. 당신의 대답에 대한 다른 사소한 문제는'DWORD'가'uint'에 매핑된다는 것입니다. –

+0

그들은 같은 크기이고 회원이'더미 (Dummy) '라고 부르기 때문에 나는 그것이 정말로 중요하다고 생각하지 않습니다. :) – Sven

관련 문제