0

我试图在这个 h 文件中调用函数 getFirstAvailableTSSComPort

http://sourceforge.net/p/yeicapi/code/11/tree/trunk/include/yei_threespace_api.h

从 h 文件中获取的相关结构和枚举(并转换为 C# 代码)

private enum TSS_Type
{
    TSS_BTL = 0,
    TSS_USB = 1,
    TSS_DNG = 2,
    TSS_WL = 3, //wireless wired (connected to PC)
    TSS_WL_W = 4, //wireless wireless
    TSS_EM = 5,
    TSS_DL = 6,
    TSS_BT = 7,
    TSS_UNKNOWN = 8
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
private struct Comport
{
    [MarshalAs(UnmanagedType.LPStr, SizeConst = 64)]
    public string Port;
    [MarshalAs(UnmanagedType.LPStr, SizeConst = 256)]
    public string FriendlyName;
    public TSS_Type Type;
}

DLL导入

[DllImport("ThreeSpace_API.dll")]
private static extern int getFirstAvailableTSSComPort([Out, MarshalAs(UnmanagedType.Struct)] out Comport port, int filter);

打电话

Comport port;
var error = getFirstAvailableTSSComPort(out port, 0);

我明白了

调用 PInvoke 函数 'YEi3!YEi3.Program::getFirstAvailableTSSComPort' 使堆栈失衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。

4

1 回答 1

3

C 代码使用cdecl调用约定,但您的 C# 代码使用stdcall. 这就是您收到 p/invoke 堆栈不平衡消息的原因。

更改DllImport以指定调用约定:

[DllImport("ThreeSpace_API.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int getFirstAvailableTSSComPort(
    out Comport port, 
    int filter
);

请注意,参数的默认编组就足够了。

此更改将解决堆栈不平衡问题,但您的代码仍将无法工作。那是因为结构翻译不正确。内联字符串需要编组为ByValTStr

[StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct ComPort {
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst=64)]
    public string com_port;
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst=256)]
    public string friendly_name;
    public TSS_Type sensor_type;
}
于 2013-03-26T15:30:24.597 回答