を渡して管理されていないC++の関数を呼び出す:ここC#の - 私は私のマネージコードから次の関数を呼び出したいLPVARIANT
short LS_LoadConfig(LS_ID SensorID,LPVARIANT varConfigPathFile,BOOL bInit)
は、私は私のC#クラス内でextern関数を宣言する方法である:
[DllImport("LineSensor.dll", EntryPoint = "#16")]
private static extern Int16 LS_LoadConfig(
Int16 deviceId,
IntPtr variantFilePath,
int init);
そして、ここで私はどのようにVARIANTインスタンスを作成し、それへのポインタを取得します。その後、私はC#の関数を呼び出す:
string filepath = @"C:\Windows\ ...";
IntPtr variantFilePath = Marshal.AllocCoTaskMem(200);
Marshal.GetNativeVariantForObject(filepath, variantFilePath);
LS_LoadConfig(device.Id, variantFilePath, initLineSensor);
問題は、私のようなエラーメッセージを受信し続けることである「LS_LoadConfig関数を呼び出すと、パラメータが管理されていない署名と一致していることを確認し、アンバランスなスタックを持っています」。
問題は、第2引数 "variantFilePath"が適切にマーシャリングされておらず、管理されていないヒープ上のサイズがアドレス(私の場合は32ビット) 。私は次のようにintにのIntPtrからC#関数のシグネチャでタイプを変更しようとしました:
[DllImport("LineSensor.dll", EntryPoint = "#16")]
private static extern Int16 LS_LoadConfig(
Int16 deviceId,
int variantFilePath,
int init);
私は乱数を渡す関数を呼び出ししようとしましたが、それは少し良くなった、私はちょうどエラー「メモリアクセスを受けています違反"。明らかに乱数は有効なアドレスではなかったためです。
誰でもこの問題の解決策を知っていますか?
ありがとうございました。
問題は、Cdeclに設定する必要がある呼び出し規約でした。したがって、[DllImport( "LineSensor.dll"、EntryPoint = "#16"、CallingConvention = CallingConvention.Cdecl)]はすべてを修正しました。 @Hansまた、refオブジェクトを渡すことはLPVARIANTを渡すことと同じですが、私の解決策よりもエレガントです。 – kean
@Kean喜んで私は助けることができました。 –