線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2855
推到 Plurk!
推到 Facebook!

由C++撰寫DLL檔讓DELPHI存取數值

 
juneo
高階會員


發表:103
回覆:190
積分:118
註冊:2004-05-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-06-24 11:20:08 IP:211.20.xxx.xxx 未訂閱
寫程式常常需要與別人撰寫的程式配合,其中一種方式就是Dll檔 今天在跟大家分享如何由C++或C語言撰寫的DLL給Delphi使用    Testdll.h // The following ifdef block is the standard way of creating macros which make exporting  // from a DLL simpler. All files within this DLL are compiled with the TESTDLL_EXPORTS // symbol defined on the command line. this symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see  // TESTDLL_API functions as being imported from a DLL, wheras this DLL sees symbols // defined with this macro as being exported. #ifdef TESTDLL_EXPORTS #define TESTDLL_API __declspec(dllexport) #else #define TESTDLL_API __declspec(dllimport) #endif    // This class is exported from the TestDll.dll class TESTDLL_API CTestDll { public:         CTestDll(void);         // TODO: add your methods here. };    extern TESTDLL_API int nTestDll;    TESTDLL_API int fnTestDll(void); TESTDLL_API DWORD fnTestDll_DWORD(void); TESTDLL_API PCHAR fnTestDll_PCHAR(void);    注意重點: TESTDLL_API int fnTestDll(void); TESTDLL_API DWORD fnTestDll_DWORD(void); TESTDLL_API PCHAR fnTestDll_PCHAR(void); 通常C語言撰寫者的DLL並不會有上面的格式, 可能只是很簡單的輸出 extern TESTDLL_API int nTestdll; TESTDLL_API char *fnTestdll(void);//這種輸出會產生呼叫錯誤    如果你要給delphi讀取可能要採用上面的三種格式的其中之一 這樣就可以由Delphi內去呼叫, 並且將Testdll.h轉成Testdll.dll 以下是Delphi呼叫的部份 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Spin, ExtCtrls; type TForm1 = class(TForm) Button1: TButton; SpinEdit1: TSpinEdit; Button2: TButton; Button3: TButton; SpinEdit2: TSpinEdit; Panel1: TPanel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; function fnTestDll_DWORD : LongInt ; external 'testDLL.DLL' index 4; //宣告要呼叫的Dll //function fnTestDll_DWORD : LongInt ; external 'testDLL.DLL'; //此種呼叫方式錯誤 function fnTestDll_PCHAR : LongInt ; external 'testDLL.DLL' index 3; //呼叫的類型不同 function fnTestDll : LongInt ; external 'testDLL.DLL' index 5; //呼叫的類型不同 implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin spinedit1.Value := fnTestDll_DWORD; //使用第一種dll呼叫 end; procedure TForm1.Button2Click(Sender: TObject); begin spinedit2.Value := fnTestDll; //使用第二種dll呼叫 end; procedure TForm1.Button3Click(Sender: TObject); begin panel1.Caption := inttostr(fnTestDll_PCHAR); //使用第三種dll呼叫 end; end. 分享比獲得更快樂
juneo
高階會員


發表:103
回覆:190
積分:118
註冊:2004-05-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-06-24 11:24:39 IP:211.20.xxx.xxx 未訂閱
function fnTestDll_DWORD : LongInt ; external 'testDLL.DLL' index 4; 請問為何我加上 index 4 就可以呼叫由C寫的Dll 但是不加上的時候就出現呼叫錯誤 雖然已經知道加上後可以呼叫,但是並不了解他的意義, 所以趁分享後也跟大家請教一下 分享比獲得更快樂
Bluemirror
一般會員


發表:2
回覆:6
積分:1
註冊:2004-07-26

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-08-15 22:00:10 IP:218.161.xxx.xxx 未訂閱
>>function fnTestDll_DWORD : LongInt ; external 'testDLL.DLL' index 4; 本行若改為 function fnTestDll_DWORD : LongInt ; external 'testDLL.DLL' name 'fnTestDll_DWORD'; 應該也可以正確動作。(: LongInt應該可以不用加,且function後之函數名稱似乎可以自己重新定義。) 以下是在DELPHI程式發展手冊裡找到的資料: ======== 以名字輸入,這種方式是以name關鍵字之後的名字來比對DLL裡的函式名稱。 以序數輸入可以減少DLL檔案load進來的時間;因為它不必到DLL函式名稱表格裡查詢函式的名字。但現在這個方法已經不建議使用了;因為Microsoft不再公佈Win32系統DLL的序數值,所以建議使用名字輸入。 ======== 以上這一段應該是針對使用Win32系統的DLL所做的建議。 可以參考看看。 >>請問為何我加上 index 4 就可以呼叫由C寫的Dll >>但是不加上的時候就出現呼叫錯誤
Bluemirror
一般會員


發表:2
回覆:6
積分:1
註冊:2004-07-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-08-16 03:16:39 IP:218.161.xxx.xxx 未訂閱
我將上面的Testdll.h 使用bcb 6的dll wizard,然後產生如下的code: //---------------------------------------------------------------------------    #include  #include //--------------------------------------------------------------------------- // Important note about DLL memory management when your DLL uses the // static version of the RunTime Library: // // If your DLL exports any functions that pass String objects (or structs/ // classes containing nested Strings) as parameter or function results, // you will need to add the library MEMMGR.LIB to both the DLL project and // any other projects that use the DLL. You will also need to use MEMMGR.LIB // if any other projects which use the DLL will be performing new or delete // operations on any non-TObject-derived classes which are exported from the // DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling // EXE's to use the BORLNDMM.DLL as their memory manager. In these cases, // the file BORLNDMM.DLL should be deployed along with your DLL. // // To avoid using BORLNDMM.DLL, pass string information using "char *" or // ShortString parameters. // // If your DLL uses the dynamic version of the RTL, you do not need to // explicitly add MEMMGR.LIB as this will be done implicitly for you //--------------------------------------------------------------------------- #pragma argsused #ifdef TESTDLL_EXPORTS #define TESTDLL_API __declspec(dllexport) #else #define TESTDLL_API __declspec(dllimport) #endif int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { return 1; } // This class is exported from the TestDll.dll class TESTDLL_API CTestDll { public: CTestDll(void); // TODO: add your methods here. }; extern TESTDLL_API int nTestDll; TESTDLL_API int fnTestDll(void); TESTDLL_API DWORD fnTestDll_DWORD(void); TESTDLL_API PCHAR fnTestDll_PCHAR(void); //--------------------------------------------------------------------------- 然後使用project->build testdll,但是在delphi中使用時, 卻顯示 “無法找到程序輸入點fnTestDll(在動態連結程式庫Testdll.dll)” 請問是哪裡的程序出了錯誤?
Bluemirror
一般會員


發表:2
回覆:6
積分:1
註冊:2004-07-26

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-08-16 03:21:36 IP:218.161.xxx.xxx 未訂閱
前兩行的include被cut掉了。 分別是: #include 〈clx.h〉 #include 〈windows.h〉
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-08-16 12:04:17 IP:147.8.xxx.xxx 未訂閱
As far as I understand, passing ojects between C /Delphi is only possible using BCB and probably with the help of ShareMem. And some C/C compiler will add a '_' prefix to all expoerted functions, so using dll index is probably a better idea.
juneo
高階會員


發表:103
回覆:190
積分:118
註冊:2004-05-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-08-17 00:28:32 IP:61.219.xxx.xxx 未訂閱
“無法找到程序輸入點fnTestDll(在動態連結程式庫Testdll.dll)” 請問是哪裡的程序出了錯誤? 這個問題是在delphi呼叫testdll.dll的時候沒有加上index4 在C裡面呼叫我就沒測試過了 分享比獲得更快樂--Juneo
系統時間:2017-12-15 17:58:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!