c#中的C ++非托管DLL

我被要求在我的项目中集成网络摄像头ZoneTrigger。 该站点提供的SDK也是C ++的样本。 我已经能够使用很少的function。 我被卡住的地方是一个函数,其中char *是传递的参数。 我做了很多挖掘,并且已经知道必须使用MarshalAs ……

我想从c ++代码导入的函数

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

错误。

我知道问题出在SpotName,它是一个字节[32],如果我不使用marshalAs,而是我只使用char它工作n给出第一个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); } 

但如果我把char []给出

 Method's type signature is not Interop compatible. ERROR 

我在这里没有选择……哪里出错了? 我应该使用MarshalAs还是char [] ??? 请帮助…..在此先感谢….

我看不到你在哪里使用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实际上是一个out参数,即你提供一个缓冲区并且ZT_EnumerateHotSpots写入它。

然后你这样称呼它

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