2011-09-06 101 views
2

我被要求在我的項目中整合webcam ZoneTrigger。該網站提供的SDK也是C++的示例。我已經能夠獲得少量功能。我被卡住的地方是一個函數,其中char *是一個傳遞的參數。我做了很多的挖掘,並已經開始知道的MarshalAs必須使用...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#

[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. 

ERROR。

我知道問題出在SpotName中,它的一個字節[32],如果我不使用marshalAs,而是我只使用字符它工作n給第一個字符.. 代碼在哪裏工作正常n給第一焦炭低於

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); 
      } 

,但如果我把的char []它給

Method's type signature is not Interop compatible. ERROR 

我在這裏已經用完的選項....我在哪裏出了錯?我應該使用MarshalAs還是char []? 請幫助..... 在此先感謝....

+0

爲什麼'ZT_TRIG_STRUCT'標記爲不安全?它不包含不安全的成員。 – Sven

+0

[MarshalAs(UnmanagedType.LPStr,SizeConst = 32)] string SpotName;不起作用? –

+0

@Preet內聯字符串應該使用'UnmanagedType.ByValTStr',而不是'LPStr';看到我的答案。 – Sven

回答

4

我看不到你在哪裏使用ZT_TRIG_STRUCT,但應該聲明如下:

[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; 
} 

其他問題,你已經在ZT_EnumerateHotSpots的聲明中。這應該是:

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

當我讀到它,SpotName實際上是一個輸出參數,即你提供一個緩衝和ZT_EnumerateHotSpots寫入到它。

然後你把這個像這樣

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

是的,你說的名字是一個out參數,需要一個StringBuilder。我沒有發現,雙關打算;)。我刪除了我的答案,並提出了你的答案。 – Sven

+0

@Sven謝謝。你的答案的另一個小問題是'DWORD'映射到'uint'。 –

+0

它們的尺寸相同,並且由於該成員被稱爲「虛擬」,我懷疑它確實很重要。 :) – Sven