C ++在C#非托管的DLL [英] C++ unmanaged DLL in c#

查看:79
本文介绍了C ++在C#非托管的DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在问到G642.44各级摄像头ZoneTrigger在我的项目。在该网站提供的SDK是C ++也样本。我已经能够得到一些功能工作。我一直停留的地方是一个函数,其中的char *是传递参数。我做了很多的挖掘,并已经开始知道的MarshalAs已经被使用...



我想从
C导入功能++代码

  //头文件
结构ZT_TRIG_STRUCT
{
INT asize的; // STRUCT大小
INT CameraIndex;
INT SpotIndex;
INT SpotType;
焦炭SpotName [32];
DWORD假人[16];
};

的typedef INT(WINAPI * f_ZT_EnumerateHotSpots)(INT SpotIndex,字符*名称,INT * SpotType);
/ *
。您的应用程序可以调用此功能是通过遍历SpotIndex参数检索有关的信息点。
名称是指向您的应用程序提供一个32字节的缓冲区。
SpotType是一个指向应用程序的32位整数。
返回值:
0 =成功,名称和SpotType已初始化与区域触发

1 =错误,我们已经失去了通信2 = Enumaration结束后,所有的景点有被枚举。您的应用程序应增加SpotIndex,直到该函数将返回区域触发
INT 2.
* /

//代码
//枚举当前点I = 0;
焦炭SpotName [32];
INT SpotType;
查看= ZT_EnumerateHotSpots(I,SpotName,&安培; SpotType);
同时(检查== 0)
{
浮动灵敏度= ZT_GetSensitivity(I)
的printf(区域触发点:%s的灵敏度:0.1F%%% \r\\\
,SpotName,灵敏度* 100);
查看= ZT_EnumerateHotSpots(++我,SpotName,&安培; SpotType);
}

转换为C#


$ B $时,

所以, b

 函数[DllImport(ZTcom.dll)] 
私人静态外部INT ZT_EnumerateHotSpots(INT I,[的MarshalAs(UnmanagedType.LPWStr)裁判串SpotName,文献INT SpotType);

公共不安全结构ZT_TRIG_STRUCT
{
公众诠释asize的; // STRUCT大小
公众诠释CameraIndex;
公众诠释SpotIndex;
公众诠释SpotType;
公共字符串SpotName;
//[MarshalAs(UnmanagedType.LPStr,SizeConst = 256)]串SpotName;
//公众的IntPtr SpotName;
}

//在代码中
INT I = 0;
串SpotName;
INT SpotType;
查看= ZT_EnumerateHotSpots(I,REF SpotName,裁判SpotType);



以上行给出:

 键入System.ExecutionEngineException引发的异常。 



错误。



我知道,问题是SpotName,它是一个字节[32],如果我不使用的MarshalAs,而不是我用的只是烧焦它的工作原理n给出的第一个字符..
,其中它工作正常n中的代码给出第一个字符是以下

 公共不安全结构ZT_TRIG_STRUCT 
{
公众诠释asize的; // STRUCT大小
公众诠释CameraIndex;
公众诠释SpotIndex;
公众诠释SpotType;
公共字符SpotName;
}

函数[DllImport(ZTcom.dll)]
私人静态外部INT ZT_EnumerateHotSpots(INT I,楼盘焦炭SpotName,楼盘INT SpotType);

公共字符SpotName;
INT I = 0;
查看= ZT_EnumerateHotSpots(I,REF SpotName,裁判SpotType);
同时(检查== 0)
{
浮动灵敏度= ZT_GetSensitivity(I)
textBox1.Text = textBox1.Text +\r\\\
+区域触发点:+ SpotName +灵敏度:+(感光度* 100)的ToString();
查看= ZT_EnumerateHotSpots(++我,裁判SpotName,裁判SpotType);
}



但如果我把的char []它给



 方法的类型签名不兼容互操作。 ERROR 



我在这里跑出选项....我在哪里出了错?我应该使用的MarshalAs或的char []?
请帮助.....
在此先感谢....


解决方案

我可以' ZT_TRIG_STRUCT T看到你正在使用,但应该声明如下:

  [StructLayout(LayoutKind.Sequential,字符集= CharSet.Ansi)] 
公共结构ZT_TRIG_STRUCT
{
公众诠释asize的;
公众诠释CameraIndex;
公众诠释SpotIndex;
公众诠释SpotType;
[的MarshalAs(UnmanagedType.ByValTStr,SizeConst = 32)]
公共字符串SpotName;
[的MarshalAs(UnmanagedType.ByValArray,SizeConst = 16)]
公共UINT []假;
}



你有另一个问题是在的声明ZT_EnumerateHotSpots 。这应该是:



 函数[DllImport(ZTcom.dll,字符集= CharSet.Ansi)] 
私有静态EXTERN INT ZT_EnumerateHotSpots(
INT SpotIndex,
StringBuilder的SpotName,
OUT INT SpotType
);



当我读它, SpotName 实际上是out参数,即您提供一个缓冲和 ZT_EnumerateHotSpots 写吧。



然后调用这个像这样

  INT SpotIndex = 0; 
StringBuilder的SpotName =新的StringBuilder(32);
INT SpotType;
INT结果= ZT_EnumerateHotSpots(SpotIndex,SpotName,出SpotType);


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

这篇关于C ++在C#非托管的DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆