none
C# 呼叫 DLL 內 class object RRS feed

  • 問題

  • Hi, 各位先進,

     我在 Math2dLib.dll 內宣告了 一個 abstract class, 和 實作 class.


    class   TAbstractTestObject   {  

              virtual   void   test(int   x)=0;  
     };

    class TTestObject (TAbstractTestObjet){
        void test(int x){  MessageBox(..'This is a test from class inside a dll.');  }
    }


    然後 export 一個 function, 傳回Create 好的 TTestObject.

    TAbstractTestObject CreateTestObject; stdcall;
    {
        return TTestObject.Create;
    }

     

    // ----------------------------------------------------------------------------------------------------------

    接著,我在 C# 內希望呼叫 Math2DLib.dll 內的 CreateTestObject(), 取得 TTestObject 物件指標。


    首先,我先宣告相同的抽象類別 ------------------------------------------
     public unsafe abstract class TAbstractTestobject
     {
      public abstract void test(int x);
     }

    然後宣告好 DLL 內 export 的函式 --------------------------------------------------
      [DllImport("Math2dLib")]
      public static extern TAbstractTestobject CreateTestObject(); 

     

    最後,當我呼叫 CreateTestObject(), 取得 TTestObject 物件指標時,程式馬上自動呼叫 TTestObject.test()

      public TAbstractTestobject TestObject = CreateTestObject(); //執行這段程式時,自動呼叫 test(),
     
    接著程式自動關閉,出現  "System.ExecutionEngineException" 的錯誤訊息。

     

    我發現只要在 DLL function 內作 Create 類別的動作, C# 呼叫該 DLL function 時就會出現錯誤。

    請問各位先進,要如何解決呢?


    Thanks,

    Daniel

    2009年9月7日 上午 01:51

解答

  • 如果 Delphi 放出的類別不是 COM automation 類別,那就沒辦法。
    因為 P/Invoke 無法支援 Win32 DLL 中的類別(必須要是 export 的函式才可以使用)。

    若是 COM automation 類別,則直接用參考加入即可。
    初學不是問題,但用不正確的態度來問問題,那就是很大的問題。
    • 已標示為解答 dan59314 2009年9月8日 上午 08:06
    2009年9月7日 上午 03:06
    版主

所有回覆

  • HI,

    您提供的程式很奇怪, 字串用單引號包裝, MessageBox也寫的很簡略, 呼叫Create方法也沒有小括號, 請貼出完整的程式, 方便測試..
    2009年9月7日 上午 02:03
  • HI,

    您提供的程式很奇怪, 字串用單引號包裝, MessageBox也寫的很簡略, 呼叫Create方法也沒有小括號, 請貼出完整的程式, 方便測試..


    因為我的 DLL 是用 Delphi 寫的,為了怕各位對 Delphi 不熟悉,所以稍微以 C++ 的方式粗略翻譯一下。  Delphi 原始碼如下:


    library Math2dLib;

    uses
      Windows, System, Math, Types, Graphics, SysUtils, Dialogs  ;

     

    {$R *.res}


    //{$DEFINE CustomDLLEntryPoint}

    type

      TAbstractTestObject=class
       procedure Test(x:integer); virtual; stdcall; abstract;
      end;

      TTestObject=class(TAbstractTestObject)
        procedure Test(x:integer); override; stdcall;
      end;


    { TTestObject }
    procedure TTestObject.Test(x: integer); stdcall;
    begin
      inherited;
      ShowMessage(format('%d This is a test from class inside a dll called',[x]));
    end;

     


    function CreateTestObject:TAbstractTestObject; stdcall;
    begin  
     Result:=TTestObject.Create;
    end;


    exports
      CreateTestObject;

    begin

    end.

    2009年9月7日 上午 02:09
  • 如果 Delphi 放出的類別不是 COM automation 類別,那就沒辦法。
    因為 P/Invoke 無法支援 Win32 DLL 中的類別(必須要是 export 的函式才可以使用)。

    若是 COM automation 類別,則直接用參考加入即可。
    初學不是問題,但用不正確的態度來問問題,那就是很大的問題。
    • 已標示為解答 dan59314 2009年9月8日 上午 08:06
    2009年9月7日 上午 03:06
    版主
  • 請問這個DLL是用Delphi Win32寫的還是Delphi .NET的
    .NET的P/Invoke無法支援 Win32 DLL 中的類別
    C#學習者,修練中,ACM解題魂 - http://kgame-blog.spaces.live.com/
    2009年9月7日 上午 03:51
  • 請問這個DLL是用Delphi Win32寫的還是Delphi .NET的
    .NET的P/Invoke無法支援 Win32 DLL 中的類別
    C#學習者,修練中,ACM解題魂 - http://kgame-blog.spaces.live.com/

    是 Delphi Win32 寫的。
    2009年9月7日 上午 03:52