C# C++;c语言中的非托管DLL#

C# C++;c语言中的非托管DLL#,c#,c++,dll,pinvoke,C#,C++,Dll,Pinvoke,我被要求在我的项目中整合网络摄像头ZoneTrigger。在站点中提供的SDK也是C++的样本。我已经能够得到一些功能的工作。我遇到的问题是一个函数,其中char*是一个传递的参数。我做了很多挖掘工作,我知道马绍拉斯必须被使用 我想从中导入的函数 C++代码< /P> 所以当转换成c时# 上列给出: Exception of type 'System.ExecutionEngineException' was thrown. 错误 我知道问题出在SpotName中,它是一个字节[32],如果我

我被要求在我的项目中整合网络摄像头ZoneTrigger。在站点中提供的SDK也是C++的样本。我已经能够得到一些功能的工作。我遇到的问题是一个函数,其中char*是一个传递的参数。我做了很多挖掘工作,我知道马绍拉斯必须被使用

我想从中导入的函数 C++代码< /P> 所以当转换成c时#

上列给出:

Exception of type 'System.ExecutionEngineException' was thrown.
错误

我知道问题出在SpotName中,它是一个字节[32],如果我不使用Marshallas,我只使用char,它工作n给出第一个char。。 下面是它工作的代码fine 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[]??? 请帮忙。。。。。
提前感谢……

我看不出您在哪里使用
ZT\u TRIG\u 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\u热点的声明
。这应该是:

[DllImport("ZTcom.dll", CharSet=CharSet.Ansi)]
private static extern int ZT_EnumerateHotSpots(
    int SpotIndex, 
    StringBuilder SpotName, 
    out int SpotType
);
正如我所读到的,
SpotName
实际上是一个out参数,即提供一个缓冲区,然后
ZT\u枚举热点
写入

那你就这样叫它吧

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

为什么
ZT\u TRIG\u STRUCT
标记为不安全?它不包含不安全的成员。[Marshallas(UnmanagedType.LPStr,SizeConst=32)]字符串SpotName;不起作用?@Preet内联字符串应使用
非托管类型.ByValTStr
,而不是
LPStr
;请看我的答案。ZT_TRIG_STRUCT是其他函数中使用的结构,还包含cam、触发器的数据,我们必须使用上述函数枚举这些数据…是的,关于名称是out参数并且需要StringBuilder,您是对的。我没发现,这是双关语;)。我删除了我的答案,并对你的答案投了赞成票。@Sven谢谢。您回答的另一个小问题是,
DWORD
映射到
uint
。它们的大小相同,而且由于成员名为
Dummy
,我怀疑这是否真的重要。:)
[DllImport("ZTcom.dll", CharSet=CharSet.Ansi)]
private static extern int ZT_EnumerateHotSpots(
    int SpotIndex, 
    StringBuilder SpotName, 
    out int SpotType
);
int SpotIndex = 0;
StringBuilder SpotName = new StringBuilder(32);
int SpotType;
int result = ZT_EnumerateHotSpots(SpotIndex, SpotName, out SpotType);