C++ unmanaged DLL in c#
I've been asked to intergrate webcam ZoneTrigger in my project. The SDK provided in the site is C++ also the sample. I've been able to get few functions to work. the place i've been stuck is a function where char* is a parameter passed. I did a lot of digging and have come to know that MarshalAs has to be used...
the function i'd like to import from c++ code
//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);
}
So when converting to 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);
the above line gives:
Exception of type 'System.ExecutionEngineException' was thrown.
ERROR.
i know that the problem is in SpotName,Its a byte[32], if i dont use marshalAs,instead i use just char it works n gives the first char.. the code where it works fine n gives first char is below
public unsafe struct ZT_TRIG_STRUCT
{
public int aSize; //STRUCT size
public int CameraIndex;
public int SpotIndex;
开发者_JAVA百科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);
}
but if i put char[] it gives
Method's type signature is not Interop compatible. ERROR
i've run out of options here.... where have i gone wrong? should i use MarshalAs or char[]??? please help..... thanks in Advance....
I can't see where you are using ZT_TRIG_STRUCT
, but that should be declared like this:
[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;
}
The other problem you have is in the declaration of ZT_EnumerateHotSpots
. That should be:
[DllImport("ZTcom.dll", CharSet=CharSet.Ansi)]
private static extern int ZT_EnumerateHotSpots(
int SpotIndex,
StringBuilder SpotName,
out int SpotType
);
As I read it, SpotName
is actually an out parameter, i.e. you supply a buffer and ZT_EnumerateHotSpots
writes to it.
You then call this like so
int SpotIndex = 0;
StringBuilder SpotName = new StringBuilder(32);
int SpotType;
int result = ZT_EnumerateHotSpots(SpotIndex, SpotName, out SpotType);
精彩评论