2016-07-28 8 views
3

C++で設計されたPLSQL Developer IDE用のプラグインとして使用されるC#DLLを作成しています。C#関数にC++ポインタを割り当てる方法

私のC#DLLは、C++ポインタを受け入れ、そのポインタを後で呼び出される関数またはメソッドに割り当てる必要があります。

IDEは、これらのプラグインをビルドするための仕様書を提供しますが、C++とDelphiのサンプルのみを提供します。私はロバートを使用していますことに注意しなければならない

:私はこれまで持って

void (*IDE_MenuState)(int ID, int Index, BOOL Enabled); 
BOOL (*IDE_Connected)(); 
void (*IDE_GetConnectionInfo)(char **Username, char **Password, char **Database); 
void (*IDE_GetBrowserInfo)(char **ObjectType, char **ObjectOwner, char **ObjectName); 

void RegisterCallback(int Index, void *Addr) 
{ 
    switch (Index) 
    { 
     case 10 : 
     (void *)IDE_MenuState = Addr; 
     break; 
     case 11 : 
     (void *)IDE_Connected = Addr; 
     break; 
     case 12 : 
     (void *)IDE_GetConnectionInfo = Addr; 
     break; 
     case 13 : 
     (void *)IDE_GetBrowserInfo = Addr; 
     break; 
    } 
} 

のC#:仕様書は、私はC++の例を提供し、この screenshot.

に含まれてより多くの情報を提供しますGieseckes Unmanaged Exports NuGet関数をエクスポートするためのパッケージ。必要に応じてこれを変更することができます。私はC#のメソッドにC++のポインタ引数を割り当てることができますどのように

public bool IDE_Connected() 
{ 
    return false; 
} 

public void IDE_MenuState(int ID, int Index, bool Enabled) 
{ 

} 

[DllExport("add", CallingConvention = CallingConvention.Cdecl, ExportName= "RegisterCallback")] 
public static void RegisterCallback(int Index, IntPtr Addr) 
{ 
    if (Index == 10) 
    { 
     // Assign IntPtr Addr to IDE_MenuState() 
     // Please help :) 
    } 
    if (Index == 11) 
    { 
     // Assign IntPtr Addr to IDE_Connected() 
     // Please help :) 
    } 

} 

+0

C#で 'void *'型を試しましたか? –

+0

AddPパラメータをintPtrからvoid *に変更できます。それではvoid * Addrをメソッドに代入するにはどうすればいいですか?ありがとう。 –

+1

'Marshal.GetDelegateForFunctionPointer()'を試すことができます –

答えて

2

実際には、実行時にコンパイルされたメソッドを変更することはできません。したがって、コード例からIDE_Connected()の機能を変更することはできません。

ただし、メソッドをdelegateshereを参照)として宣言し、それぞれの静的インスタンスを作成できます。私はこれをテストしていませんが、その代わりにchar**の、out char[]またはより良い、out stringを使用するIDE_GetConnectionInfoIDE_GetBrowserInfoのメソッドのシグネチャを変更してみてください:

public unsafe class MyClass 
{ 
    delegate void IDE_MenuState(int ID, int Index, bool Enabled); 
    delegate bool IDE_Connected(); 
    delegate void IDE_GetConnectionInfo(char** Username, char** Password, char** Database); 
    delegate void IDE_GetBrowserInfo(char** ObjectType, char** ObjectOwner, char** ObjectName); 

    static IDE_MenuState method_IDE_MenuState; 
    static IDE_Connected method_IDE_Connected; 
    static IDE_GetConnectionInfo method_IDE_GetConnectionInfo; 
    static IDE_GetBrowserInfo method_IDE_GetBrowserInfo; 

    public static void RegisterCallback(int Index, IntPtr Addr) 
    { 
     switch (Index) 
     { 
      case 10: 
       method_IDE_MenuState = (IDE_MenuState)Marshal.GetDelegateForFunctionPointer(Addr, typeof(IDE_MenuState)); 
       break; 
      case 11: 
       method_IDE_Connected = (IDE_Connected)Marshal.GetDelegateForFunctionPointer(Addr, typeof(IDE_Connected)); 
       break; 
      case 12: 
       method_IDE_GetConnectionInfo = (IDE_GetConnectionInfo)Marshal.GetDelegateForFunctionPointer(Addr, typeof(IDE_GetConnectionInfo)); 
       break; 
      case 13: 
       method_IDE_GetBrowserInfo = (IDE_GetBrowserInfo)Marshal.GetDelegateForFunctionPointer(Addr, typeof(IDE_GetBrowserInfo)); 
       break; 
     } 
    } 

    public static void IDE_MenuState(int ID, int Index, bool Enabled) 
    { 
     if (method_IDE_MenuState == null) 
     { 
      throw new MissingMethodException("IDE_MenuState has not been assigned pointer yet."); 
     } 
     method_IDE_MenuState(ID, Index, Enabled); 
    } 

    public static bool IDE_Connected() 
    { 
     if (method_IDE_Connected == null) 
     { 
      throw new MissingMethodException("IDE_Connected has not been assigned pointer yet."); 
     } 
     return method_IDE_Connected(); 
    } 

    public static void IDE_GetConnectionInfo(char** Username, char** Password, char** Database) 
    { 
     if (method_IDE_GetConnectionInfo == null) 
     { 
      throw new MissingMethodException("IDE_GetConnectionInfo has not been assigned pointer yet."); 
     } 
     method_IDE_GetConnectionInfo(Username, Password, Database); 
    } 

    public static void IDE_GetBrowserInfo(char** ObjectType, char** ObjectOwner, char** ObjectName) 
    { 
     if (method_IDE_GetBrowserInfo == null) 
     { 
      throw new MissingMethodException("IDE_GetBrowserInfo has not been assigned pointer yet."); 
     } 
     method_IDE_GetBrowserInfo(ObjectType, ObjectOwner, ObjectName); 
    } 
} 

注:これを試してみてください。これはあなたのAPIをC#でより有用にするでしょう。

+0

あなたの助けをもう一度お返事ありがとうございます。 –

関連する問題