1

そこで、C ++で開発されたDLLの関数をC#プロジェクトにエクスポートしようとしています。オンラインで調べて本の調査も行った後、私はそうする方法を見つけました。しかし、これへの私の露出は限られており、私の知識はすべて自己緊張しているので、どこかで何かを台無しにしたと確信しています。

私は次のように関数をエクスポートしています:

STDMETHODIMP __export DataSetpImpl::set_HeaderFile(BSTR Value)

そしてそれをそのようにインポートします:

public unsafe class test
{
  const string _dllLocation = "DllPath.dll";
  [DLLImport(_dllLocation, CallingConvention = CallingConvention.stdCall)]
  [return: MarshalAs(UnmanagedType.Bstr)]
  public static extern string set_HeaderFile([MarshalAs(UnmanagedType.BStr)] String path);
}

次に、アプリケーションで次のように呼び出します。

test.set_HeaderFile(@"C:\temp\SomeHeaderFile.hdz");

すべてが正しくビルドされ、正常にリンクされます...アプリケーションが上記の呼び出しにヒットすると、問題が発生します。それはスローし、次のようにエラーが発生します。

Unable to find an entry point named 'set_HeaderFile' in DLL 'DLLPath.dll'.

私が間違っていることについて何か考えはありますか?また、非常に限られている場合は、このテーマに関する私の知識を覚えておいてください。オンラインやオフィス周辺のメモで見つけたものをそのまま使用します。

4

2 に答える 2

2

この方法では、クラス以外のメンバー関数のみをインポートできます。

この場合の「set_HeaderFile」という名前は「DataTableImpl$$set_HeaderFile @ 4」のような名前に変更され、静的として宣言されていても、CLRは「set_HeaderFile」という名前を使用して.dllファイルでこれを検出しません。

回避策を作成できます。

あなたが持っていると言う

DataSetpImpl* g_Instance;

次に、関数を記述します

LONG __stdcall mySetHeaderFile(BSTR Val)
{
    return g_Instance->set_HeaderFile(Val);
}

次に、C#でアクセスできます。

[DLLImport(_dllLocation, CallingConvention = CallingConvention.stdCall, EntryPoint="mySetHeaderFile")]
public static extern Int32 set_HeaderFile([MarshalAs(UnmanagedType.BStr)] String path);

BSTRを返すには、マーシャリングを使用したラッピングも必要です。これを参照してください:http://msdn.microsoft.com/en-us/library/7b620dhe.aspx

于 2012-06-29T14:47:26.853 に答える
0

マネージコードとの相互作用の2つの方法を混同していると思います。コードをCOMサーバーでラップし、.NETのCOM相互運用機能を利用できます。または、非クラス(つまり、グローバルスコープ)のエクスポートされた関数を作成して、P/Invokeを使用することもできます。

関数の言い回しはCOMを示唆しています。しかし、C#側では、間違ってP/Invokeを使用します。

P/Invokeを使用することをお勧めします。COMは大きなトピックです。あなたがたくさん学ぶ気がない限り、そこに行かないでください。

P / Invokable関数の場合、非クラス関数を作成します。P/Invokeを介してDLLからエクスポートされたC++クラスを使用することはできません。2つのクラスシステム(マネージドとC ++)はまったく異なります。また、BSTRを渡す必要はありません。古き良きLPCWSTRを使用すれば、P/Invokeで問題ありません。

于 2012-06-29T14:47:52.267 に答える