简体   繁体   English

C#中的C ++非托管DLL

[英]C++ unmanaged DLL in c#

I've been asked to intergrate webcam ZoneTrigger in my project. 我被要求在我的项目中集成网络摄像头ZoneTrigger。 The SDK provided in the site is C++ also the sample. 该站点提供的SDK是C ++,也是示例。 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. 我被卡住的地方是一个函数,其中char *是传递的参数。 I did a lot of digging and have come to know that MarshalAs has to be used... 我做了很多挖掘工作,发现必须使用MarshalAs ...

the function i'd like to import from c++ code 我想从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);
}

So when converting to c# 所以在转换为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 我知道问题出在SpotName,它是一个字节[32],如果我不使用marshalAs,而是我只使用char,它的工作原理是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);
            }

but if i put char[] it gives 但是如果我把char []给

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[]??? 我应该使用MarshalAs还是char [] ??? please help..... thanks in Advance.... 请帮助...。在此先感谢...。

I can't see where you are using ZT_TRIG_STRUCT , but that should be declared like this: 我看不到您在哪里使用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;
}

The other problem you have is in the declaration of ZT_EnumerateHotSpots . 您遇到的另一个问题是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, ie you supply a buffer and ZT_EnumerateHotSpots writes to it. 在我读到它时, SpotName实际上是一个out参数,即,您提供一个缓冲区,然后ZT_EnumerateHotSpots写入。

You then call this like so 然后您这样称呼它

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM