C++で記述されたサードパーティからのDLLがあります。以下は、dllのドキュメントからの情報です。
//start documentation
RECO_DATA{
wchar_t Surname[200];
wchar_t Firstname[200];
}
説明:関数の結果を受け取るためのデータ構造。すべての関数の結果はUnicode(UTF-8)として保存されます。
方法:
bool recoCHN_P_Name(char *imgPath,RECO_DATA *o_data);
入力:
char * imgPath
この関数が認識する画像の場所の完全なパス
RECO_DATA * o_data
関数結果を受け取るためのデータオブジェクト。関数の戻り値:成功の場合はtrue、それ以外の場合はfalseが返されます。
//end documentation
C#アプリケーションからrecoCHN_P_Nameを呼び出そうとしています。この目的のために、私はこのコードを思いつきました:
DLLをインポートするコード:
public class cnOCRsdk
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct RECO_DATA{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=200)]
public string FirstName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)]
public string Surname;
}
[DllImport(@"cnOCRsdk.dll", EntryPoint="recoCHN_P_Name")]
public static extern bool recoCHN_P_Name(byte[] imgPath, RECO_DATA o_data);
}
関数を呼び出すコード:
cnOCRsdk.RECO_DATA recoData = new cnOCRsdk.RECO_DATA();
string path = @"C:\WINDOWS\twain_32\twainrgb.bmp";
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] bytes = encoding.GetBytes(path);
bool res = cnOCRsdk.recoCHN_P_Name(bytes, recoData);
そして、私が得ているエラーは、「DLL 'cnOCRsdk.dll'に 'recoCHN_P_Name'という名前のエントリポイントが見つかりません。」というエラーです。型をC++からC#に変換しますが、正確には...?
まず、関数が実際にエクスポートされていることを確認します。
Visual Studioコマンドプロンプトで、dumpbin /exports whatever.dll
を使用します
C#はC++名のマングリングをサポートしていないため、C++関数を次のように宣言する必要があります
extern "C" {...}
(サードパーティ製の場合はオプションではない場合があります)、または正常に機能する場合は、マングルされた名前を直接呼び出します。サードパーティに機能のマングル化されていないインターフェイスを提供させるほうが簡単な場合があります。
解決済み-少なくともプログラムが壊れず、実際にブール値を返すところまで。
キーは、おそらく、「破損した」名前としてエントリポイントを指定することでした
[DllImport(@"cnOCRsdk.dll", EntryPoint="?recoCHN_P_Name@CcnOCRsdk@@QAE_NPADPAURECO_DATA@@@Z")]
public static extern bool recoCHN_P_Name(ref string imgPath, ref RECO_DATA o_data);
その後、他のエラーが発生しましたが、「エントリポイントが見つかりません」と表示されなくなりました。
C++/CLIを使用してラッパーを記述します。このラッパーは、.hファイルをインクルードし、サードパーティベンダーから入手した.libファイルにリンクできます。次に、C#プログラム用のマネージインターフェイスを作成することは簡単かつ安全です。
私はこれらのステップで同じ問題を解決しました:
手順1) Visual Studioを使用してC++でカスタムDLLをプログラムする場合、プロジェクトのプロパティページでCommon Language Runtime Support (/clr)
parameterからCommon Language Runtime Support (/clr)
へ。
ステップ2) _.h
_ファイルで関数の減速を行うには、以下のような__declspec(dllexport)
キーワードを使用します。
___declspec(dllexport) double Sum(int a,int b);
_
手順3)ビルドおよびエクスポートDLLファイル、次にDependency Walkerソフトウェアを使用して関数を取得EntryPoint 。
step4)インポートDLL file in the C#project and set EntryPoint and CallingConvention variable以下のように:
_[DllImport("custom.dll", EntryPoint = "?Sum@@YAXHHHHHHNNN@Z", CallingConvention = CallingConvention.Cdecl)]
public static extern double Sum(int a,int b);
_
DllImportでCallingConventionを指定するときに、符号化されていない名前を使用してみることができます
正しいEntryPoint文字列は、メインの管理されていないdllに付属する「.lib」ファイルにあります。