2010-09-16 64 views
0

我有以下在一個DLL中定義函數:問題DLL調用以書面形式調用進程

__declspec(dllexport) int __stdcall 
mjscall(char *cmd, DWORD wtime, char *stdoutfile, char *stderrfile) 

我需要編寫一個程序來調用上面的函數。 我正在做第一次,我沒有太多的想法。 我已經寫以下代碼

#include <windows.h> 
#include <windows.h> 
#include <stdio.h> 
#include <io.h> 
#include <stdlib.h> 
#include <limits.h> 
extern __declspec(dllexport) int __stdcall mjscall(char *cmd, DWORD wtime, char *stdoutfile, char *stderrfile); 
typedef INT (*MJSCALL) (char *,DWORD, char *, char *); 
int main() 
{ 

    char *a,*b,*c; 
    a=NULL; 
    b=NULL; 
    c=NULL; 
    DWORD aa =1; 
    int i; 
    HMODULE hLib; 
    MJSCALL ADD; 
    hLib=LoadLibrary("f3cucall.dll"); 
    if(hLib==NULL) 
    { 
     return 1; 
    } 
    ADD=(MJSCALL)GetProcAddress(hLib,"mjscall"); 
    if (ADD==NULL) 
    { 
     return 1; 
    } 

    (ADD)(a,aa,b,c); 
    return 0; 
} 

的 「(ADD)(A,AA,B,C);」正在造成這個問題。 有人可以幫我嗎?

回答

1

我想你攪拌兩次的事情了:從DLL(通知鏈接這樣做),並從一個DLL的__declspec(dllimport)進口功能
__declspec(dllexport) MSVC關鍵字出口功能。這是在加載時完成的,鏈接器將創建所有必要的代碼來加載DLL並解析符號。實際上,它會向exe文件添加一些代碼,以便讓操作系統加載DLL。就像任何正常的內部函數一樣,您可以使用__declspec(dllimport)聲明的函數。

如果您想使用這種方法,您需要DLL的lib文件,因爲它包含鏈接器解析符號名稱的信息。它實際上並不包含代碼,只有這些鏈接器的DLL信息。另外,你必須告訴鏈接器你要使用的函數位於DLL中,在函數聲明前使用魔術__declspec(dllimport)。這就是爲什麼你提供一個.lib和一個頭文件(包含這些聲明)與你的DLL,如果你想這樣做。您應該在更改DLL時重建使用該DLL的項目,因爲.lib文件可能已更改。 您可以使用您的DLL項目相同的頭文件和項目,從這個DLL導入:

#ifdef MYDLL_EXPORTS 
#define MYDLL_API __declspec(dllexport) 
#else 
#define MYDLL_API __declspec(dllimport) 
#endif 

MYDLL_API void printMe(int);

的MyDLL_API得到解決要麼__declspec(dllexport)的(在DLL項目,您在定義MYDLL_EXPORTS項目設置)或__declspec(dllimport)(在所有使用dll的項目中)。這樣,您只需要一個DLL的頭文件。

調用DLL函數的另一種方法是使用LoadLibrary和GetProcAdress。這兩個用於在運行時加載DLL。在加載時和運行時加載DLL的主要區別在於,您可以在運行時加載DLL,而操作系統將在加載時加載DLL時執行該任務(例如,如果在加載時顯示消息框DLL無法找到並且不運行該進程)。