API を実装するネイティブ DLL があります。C++ ヘッダーは次のようになります。
class CAPIInterface
{
public:
virtual int __stdcall Release()=0;
virtual LPCSTR __stdcall ErrorDescription(const int code)=0;
virtual int __stdcall Login(const int login,LPCSTR password)=0;
}
C++ では、インターフェイスへのポインターは次のように取得されます。
typedef int (*APICreate_t)(int version,CAPIInterface **api);
pfnAPICreate =reinterpret_cast<APICreate_t>(::GetProcAddress(hlib,"APICreate"));
CAPIInterface *api=NULL;
if(pfnAPICreate) (*pfnAPICreate)(version,&api);
インターフェイスのメソッドは次のように呼び出されます。
api->Login(123,"password");
次に、このネイティブ DLL をロードし、C# プログラムで API を使用する必要があります。この方法で DLL をロードし、ネイティブ インターフェイスへのポインターを取得することができました。
public static class GlobalMembers
{
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public delegate int APICreate_t(time_t version, out IntPtr api);
}
ptr_pfnAPICreate = NativeMethods.GetProcAddress(hlib,"APICreate");
pfnAPICreate = (GlobalMembers.APICreate_t)Marshal.GetDelegateForFunctionPointer(ptr_pfnAPICreate, typeof(GlobalMembers.APICreate_t));
pfnAPICreate(version, out mptr);
しかし、このポインター (mptr) をインターフェイスの C# 実装にマップする方法がわかりません。また、C# でインターフェイス CAPIInterface を宣言する方法もわかりません。この方法でインターフェースを宣言しようとしました:
[StructLayout(LayoutKind.Sequential)]
public class CAPIInterface
{
public delegate int Release();
public delegate string ErrorDescription(int code);
public delegate int Login(int login, string password);
}
しかし、それはコンパイルされません... 次のエラーが返されます: エラー 3 非呼び出し可能メンバー 'CAPIInterface.Login' はメソッドのように使用できません。デリゲートもどこかでインスタンス化する必要があることは理解しています...しかし、それを行う方法は? 上記のように CAPIInterface を宣言するのは正しいアプローチですか?