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

DllImport

[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 に答える