gpt4 book ai didi

c# - C# 中的 C++ 非托管 DLL

转载 作者:搜寻专家 更新时间:2023-10-31 01:18:16 25 4
gpt4 key购买 nike

我被要求在我的项目中集成网络摄像头 ZoneTrigger。站点中提供的 SDK 也是 C++ 示例。我已经能够使用一些功能。我被卡住的地方是一个函数,其中 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 给出第一个字符在下面

 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 实际上是一个输出参数,即您提供一个缓冲区并向其写入 ZT_EnumerateHotSpots

然后你这样调用它

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

关于c# - C# 中的 C++ 非托管 DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7318613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com