私は熟練したソフトウェアエンジニアですが、C#ではいくぶん新しくなっています。私は示されているようにCインターフェイスを持つC++オブジェクトで構成されたDLLを持っています。私はC#アプリケーションからDLL内のC++エントリポイントにアクセスする方法があるかどうかわからなかったので、このCインターフェイスを使用しました。DLLとの間でオブジェクトポインタを渡す方法は?
__declspec(dllexport) void *Constructor();
__declspec(dllexport) void Destructor(void *pObj);
__declspec(dllexport) int Method(void *pObj, char *pSrcDst, int len);
これは上記のインターフェイスのCコードです。
extern "C" void *Constructor()
{
return (void *)new Object;
}
extern "C" void Destructor(void *pObj)
{
delete (Object *)pObj;
}
extern "C" int Method(void *pObj, char *pSrcDst, int len)
{
if (!pObj) return 0;
return ((Object *)pObj)->Method(pSrcDst, len);
}
これまでのところとても良いです。今、私はC#アプリケーションからこのインタフェースにアクセスできる必要があります。私が学んだことから、私は次のC#インターフェイスを実装しました。
unsafe public class Wrapper
{
[SuppressUnmanagedCodeSecurityAttribute()]
[DllImport("MyDLL.dll")]
public static extern
IntPtr Constructor();
[SuppressUnmanagedCodeSecurityAttribute()]
[DllImport("MyDLL.dll")]
public static extern
void Destructor(IntPtr pObj);
[SuppressUnmanagedCodeSecurityAttribute()]
[DllImport("MyDLL.dll")]
public static extern
int Method(IntPtr pObj, [In,Out] byte[] pSrcDst, int len);
ここでは、上記のインターフェイスを使用するC#コードを示します。
private IntPtr pObject;
public object()
{
pObject = Wrapper.Constructor();
}
~object()
{
Wrapper.Destructor(pObject);
}
public override byte[] method()
{
byte[] bytes = new byte[100];
int converted = Wrapper.Method(pObject, bytes, bytes.length);
return bytes;
}
コードは、Wrapper.MethodとWrapper.Destructorの両方の呼び出しでアサートされます。私は、オブジェクトへのポインタを適切に処理していないと仮定します。助言がありますか?
「コードが主張する」とはどういう意味ですか?エラーメッセージが表示されますか? – svick
はい、 'PInvokeStackImbalanceが検出されました'。 –
ほとんどのコンパイラでは、 'extern" C "関数は例外をスローしないと考えています(特にCコードがそれらを呼び出す場合)。したがって、' new Object() 'ビットを必ず例外(特に 'std :: bad_alloc')がエスケープされないようにするための例外ブロックです。 –