如何动态调用DLL?

yimingsoft 2005-09-13 07:07:35
编程中我遇到了一个动态编译的DLL,没有.LIB 和.H
在APP中如下调用 ,可是我在其他类中如何使用这些函数呀?


//函数定义
typedef LONG (CALLBACK* LPFNDLLFUNC1)(LONG);
// 定义一个函数指针的类型 LPFNDLLFUNC1 , 这个类型是自己定义的,类型名为 LPFNDLLFUNC1

typedef LONG (CALLBACK* LPFNDLLFUNC2)(LONG);
typedef LONG (CALLBACK* LPFNDLLFUNC3)(LONG,CHAR *,CHAR *);
typedef LONG (CALLBACK* LPFNDLLFUNC4)(LONG,CHAR *,CHAR *);
typedef LONG (CALLBACK* LPFNDLLFUNC5)(LONG);
typedef LONG (CALLBACK* LPFNDLLFUNC6)();

HINSTANCE hInsDLL;
LPFNDLLFUNC1 fnInitModem; // Function pointer 1 这里利用自己定义的类型名LPFNDLLFUNC1定义了一个fnInitModem的函数指针!
LPFNDLLFUNC2 fnCloseModem; // Function pointer 2
LPFNDLLFUNC3 fnSendMsg; // Function pointer 3
LPFNDLLFUNC4 fnReadMsgEx; // Function pointer 4
LPFNDLLFUNC5 fnGetStatus; // Function pointer 5
LPFNDLLFUNC5 fnGetSndCount;
LPFNDLLFUNC5 fnGetRecCount;
LPFNDLLFUNC5 fnClrSndBuf;
LPFNDLLFUNC5 fnClrRecBuf;
LPFNDLLFUNC6 fnDogSerial;


//====------------------------------------------------
//取得函数地址
hInsDLL=LoadLibrary("MonDem");
if(hInsDLL==NULL){
ShowMessageNULL( IDS_LOADDLL_FAILED );
} else {
fnInitModem = (LPFNDLLFUNC1)GetProcAddress(hInsDLL,"fnInitModem");
fnCloseModem = (LPFNDLLFUNC2)GetProcAddress(hInsDLL,"fnCloseModem");
fnSendMsg = (LPFNDLLFUNC3)GetProcAddress(hInsDLL,"fnSendMsg");
fnReadMsgEx = (LPFNDLLFUNC4)GetProcAddress(hInsDLL,"fnReadMsgEx");
fnGetStatus = (LPFNDLLFUNC5)GetProcAddress(hInsDLL,"fnGetStatus");
fnGetSndCount = (LPFNDLLFUNC5)GetProcAddress(hInsDLL,"fnGetSndCount");
fnGetRecCount = (LPFNDLLFUNC5)GetProcAddress(hInsDLL,"fnGetRecCount");
fnClrSndBuf = (LPFNDLLFUNC5)GetProcAddress(hInsDLL,"fnClrSndBuf");
fnClrRecBuf = (LPFNDLLFUNC5)GetProcAddress(hInsDLL,"fnClrRecBuf");
fnDogSerial = (LPFNDLLFUNC6)GetProcAddress(hInsDLL,"fnDogSerial");
}

...全文
367 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
yimingsoft 2005-09-14
  • 打赏
  • 举报
回复
我要哭死了!
yimingsoft 2005-09-14
  • 打赏
  • 举报
回复
我也奇怪啊!
Page1.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnInitModem)(long)" (?fnInitModem@@3P6GJJ@ZA)
Debug/CYBSm.exe : fatal error LNK1120: 1 unresolved externals
怎么还是不认识呢?我包含头文件了 #include "CYBSm.h"!
phoenix96_2000 2005-09-14
  • 打赏
  • 举报
回复
你哪儿出错了?

testfn.h:

#pragma once
#include <windows.h>
typedef LONG (CALLBACK * LPFNDLLFUNC1)(LONG);
extern LPFNDLLFUNC1 fnInitModem;


testfn.cpp
#include "stdafx.h"
#include "testfn.h"

LPFNDLLFUNC1 fnInitModem = NULL;


main.cpp:
#include "stdafx.h"
#include "testfn.h"

int main()
{
//先初始化fnInitModem... LoadLibrary, GetProcAddress..

long l = fnInitModem(0);

return 0;
}

完全OK啊
yimingsoft 2005-09-14
  • 打赏
  • 举报
回复
我是那么做的 可是据不好使
???????
#include "CYBSm.h"



UpdateData(TRUE);
int nRc;
if(m_iComPort==8)
{
nRc= fnInitModem(-1); //所有端口
}
else nRc= fnInitModem(m_iComPort); //端口1-8

if(nRc==0) MessageBox("初始化成功");
else {
CString csTmp;
csTmp.Format("初始化失败,错误代码 %d",nRc);
MessageBox(csTmp);



Page1.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnInitModem)(long)" (?fnInitModem@@3P6GJJ@ZA)
Debug/CYBSm.exe : fatal error LNK1120: 1 unresolved externals


phoenix96_2000 2005-09-14
  • 打赏
  • 举报
回复
#include "xxx.h"
就和函数调用一样使用
long lRetCode = (fnInitModem)(1);
yimingsoft 2005-09-14
  • 打赏
  • 举报
回复
太谢谢了!!!!!!!!!!!!!!!!!!!好使用了!!!
但是我要在其他的类中怎么使用函数啊?直接写 fnInitModem( 0) ; 而函数fnInitModem 他又不认识!
也不能再这么写了啊 LPFNDLLFUNC1 fnInitModem(1)
yimingsoft 2005-09-14
  • 打赏
  • 举报
回复
太谢谢了!!!!!!!!!!!!!!!!!!!好使用了!!!
但是我要在其他的类中怎么使用函数啊?直接写 fnInitModem( 0) ; 而函数fnInitModem 他又不认识!
phoenix96_2000 2005-09-14
  • 打赏
  • 举报
回复
写反了,
extern .. 放在.h里面..
.h
extern LPFNDLLFUNC1 fnInitModem;

.cpp
LPFNDLLFUNC1 fnInitModem = NULL;
yimingsoft 2005-09-14
  • 打赏
  • 举报
回复
我把程序摘出来吧

// CYBSm.h : main header file for the CYBSM application


#if !defined(AFX_CYBSM_H__DD9BDCF0_2D64_4907_A7D0_05E0455718DE__INCLUDED_)
#define AFX_CYBSM_H__DD9BDCF0_2D64_4907_A7D0_05E0455718DE__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h" // main symbols

/////////////////////////////////////////////////////////////////////////////
// CCYBSmApp:
// See CYBSm.cpp for the implementation of this class
//


//====------------------------------------------------
//函数定义
typedef LONG (CALLBACK* LPFNDLLFUNC1)(LONG);
// 定义一个函数指针的类型 LPFNDLLFUNC1 , 这个类型是自己定义的,类型名为 LPFNDLLFUNC1


typedef LONG (CALLBACK* LPFNDLLFUNC2)(LONG);
typedef LONG (CALLBACK* LPFNDLLFUNC3)(LONG,CHAR *,CHAR *);
typedef LONG (CALLBACK* LPFNDLLFUNC4)(LONG,CHAR *,CHAR *);
typedef LONG (CALLBACK* LPFNDLLFUNC5)(LONG);
typedef LONG (CALLBACK* LPFNDLLFUNC6)();

extern LPFNDLLFUNC1 fnInitModem; // Function pointer 1 这里利用自己定义的类型名
extern LPFNDLLFUNC2 fnCloseModem; // Function pointer 2
extern LPFNDLLFUNC3 fnSendMsg; // Function pointer 3
extern LPFNDLLFUNC4 fnReadMsgEx; // Function pointer 4
extern LPFNDLLFUNC5 fnGetStatus; // Function pointer 5
extern LPFNDLLFUNC5 fnGetSndCount;
extern LPFNDLLFUNC5 fnGetRecCount;
extern LPFNDLLFUNC5 fnClrSndBuf;
extern LPFNDLLFUNC5 fnClrRecBuf;
extern LPFNDLLFUNC6 fnDogSerial;

class CCYBSmApp : public CWinApp
{
public:
void ReadSetting();
CCYBSmApp();
private:
HANDLE m_hOnceMutex;

public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCYBSmApp)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL

// Implementation
//{{AFX_MSG(CCYBSmApp)
afx_msg void OnAppAbout();
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// CYBSm.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "CYBSm.h"

#include "MainFrm.h"
#include "CYBSmDoc.h"
#include "CYBSmView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



/////////////////////////////////////////////////////////////////////////////
// CCYBSmApp

BEGIN_MESSAGE_MAP(CCYBSmApp, CWinApp)
//{{AFX_MSG_MAP(CCYBSmApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCYBSmApp construction

CCYBSmApp::CCYBSmApp():m_hOnceMutex(NULL)
{

}
/////////////////////////////////////////////////////////////////////////////
// The one and only CCYBSmApp object

CCYBSmApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CCYBSmApp initialization

BOOL CCYBSmApp::InitInstance()
{

AfxEnableControlContainer();


#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif

// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.



/////////////////////////////////////////////////////////////////////////////////////

LoadStdProfileSettings(); // Load standard INI file options (including MRU)


// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.

CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MENU_YB, //设置图标
RUNTIME_CLASS(CCYBSmDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CCYBSmView));
AddDocTemplate(pDocTemplate);

// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;

//====------------------------------------------------
//取得函数地址

HINSTANCE hInsDLL;
hInsDLL=LoadLibrary("MonDem");
if(hInsDLL==NULL){
ShowMessageNULL( IDS_LOADDLL_FAILED );
} else {
fnInitModem = (LPFNDLLFUNC1)GetProcAddress(hInsDLL,"fnInitModem");
fnCloseModem = (LPFNDLLFUNC2)GetProcAddress(hInsDLL,"fnCloseModem");
fnSendMsg = (LPFNDLLFUNC3)GetProcAddress(hInsDLL,"fnSendMsg");
fnReadMsgEx = (LPFNDLLFUNC4)GetProcAddress(hInsDLL,"fnReadMsgEx");
fnGetStatus = (LPFNDLLFUNC5)GetProcAddress(hInsDLL,"fnGetStatus");
fnGetSndCount = (LPFNDLLFUNC5)GetProcAddress(hInsDLL,"fnGetSndCount");
fnGetRecCount = (LPFNDLLFUNC5)GetProcAddress(hInsDLL,"fnGetRecCount");
fnClrSndBuf = (LPFNDLLFUNC5)GetProcAddress(hInsDLL,"fnClrSndBuf");
fnClrRecBuf = (LPFNDLLFUNC5)GetProcAddress(hInsDLL,"fnClrRecBuf");
fnDogSerial = (LPFNDLLFUNC6)GetProcAddress(hInsDLL,"fnDogSerial");
}
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);
m_pMainWnd->UpdateWindow();
m_pMainWnd->SetWindowText("短信息平台");
AfxBeginThread( ThreadFn ,this);

return TRUE;
}

编译信息
Linking...
CYBSm.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnDogSerial)(void)" (?fnDogSerial@@3P6GJXZA)
CYBSm.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnClrRecBuf)(long)" (?fnClrRecBuf@@3P6GJJ@ZA)
CYBSm.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnClrSndBuf)(long)" (?fnClrSndBuf@@3P6GJJ@ZA)
CYBSm.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnGetRecCount)(long)" (?fnGetRecCount@@3P6GJJ@ZA)
CYBSm.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnGetSndCount)(long)" (?fnGetSndCount@@3P6GJJ@ZA)
CYBSm.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnGetStatus)(long)" (?fnGetStatus@@3P6GJJ@ZA)
CYBSm.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnReadMsgEx)(long,char *,char *)" (?fnReadMsgEx@@3P6GJJPAD0@ZA)
CYBSm.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnSendMsg)(long,char *,char *)" (?fnSendMsg@@3P6GJJPAD0@ZA)
CYBSm.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnCloseModem)(long)" (?fnCloseModem@@3P6GJJ@ZA)
CYBSm.obj : error LNK2001: unresolved external symbol "long (__stdcall* fnInitModem)(long)" (?fnInitModem@@3P6GJJ@ZA)
没有找到外部符号?怎么不认识这些函数啊


/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CYBSM_H__DD9BDCF0_2D64_4907_A7D0_05E0455718DE__INCLUDED_)
yimingsoft 2005-09-14
  • 打赏
  • 举报
回复
我把函数声明放在.h中,函数实现放在。cpp中,.CPP里用extern LPFNDLLFUNC1 fnInitModem;
结果出现了200多个错误?????????????????

CYBSm.h:
//====------------------------------------------------
//函数定义
typedef LONG (CALLBACK* LPFNDLLFUNC1)(LONG);
// 定义一个函数指针的类型 LPFNDLLFUNC1 , 这个类型是自己定义的,类型名为 LPFNDLLFUNC1

typedef LONG (CALLBACK* LPFNDLLFUNC2)(LONG);
typedef LONG (CALLBACK* LPFNDLLFUNC3)(LONG,CHAR *,CHAR *);
typedef LONG (CALLBACK* LPFNDLLFUNC4)(LONG,CHAR *,CHAR *);
typedef LONG (CALLBACK* LPFNDLLFUNC5)(LONG);
typedef LONG (CALLBACK* LPFNDLLFUNC6)();

HINSTANCE hInsDLL;
LPFNDLLFUNC1 fnInitModem; // Function pointer 1 这里利用自己定义的类型名LPFNDLLFUNC1定义了一个fnInitModem的函数指针!
LPFNDLLFUNC2 fnCloseModem; // Function pointer 2
LPFNDLLFUNC3 fnSendMsg; // Function pointer 3
LPFNDLLFUNC4 fnReadMsgEx; // Function pointer 4
LPFNDLLFUNC5 fnGetStatus; // Function pointer 5
LPFNDLLFUNC5 fnGetSndCount;
LPFNDLLFUNC5 fnGetRecCount;
LPFNDLLFUNC5 fnClrSndBuf;
LPFNDLLFUNC5 fnClrRecBuf;
LPFNDLLFUNC6 fnDogSerial;


CYBSm.cpp

extern LPFNDLLFUNC1 fnInitModem;
extern LPFNDLLFUNC2 fnCloseModem; // Function pointer 2
extern LPFNDLLFUNC3 fnSendMsg; // Function pointer 3
extern LPFNDLLFUNC4 fnReadMsgEx; // Function pointer 4
extern LPFNDLLFUNC5 fnGetStatus; // Function pointer 5
extern LPFNDLLFUNC5 fnGetSndCount;
extern LPFNDLLFUNC5 fnGetRecCount;
extern LPFNDLLFUNC5 fnClrSndBuf;
extern LPFNDLLFUNC5 fnClrRecBuf;
extern LPFNDLLFUNC6 fnDogSerial;
phoenix96_2000 2005-09-14
  • 打赏
  • 举报
回复

LPFNDLLFUNC1 fnIniModem = NULL;

是放到.cpp文件里面,写错了
yimingsoft 2005-09-14
  • 打赏
  • 举报
回复
我把函数定义放在了。h中 然后如下写,但是有错误。我怎么经常登陆不了CSDN的技术社区呢?

//====------------------------------------------------
//函数定义
typedef LONG (CALLBACK* LPFNDLLFUNC1)(LONG);
// 定义一个函数指针的类型 LPFNDLLFUNC1 , 这个类型是自己定义的,类型名为 LPFNDLLFUNC1

typedef LONG (CALLBACK* LPFNDLLFUNC2)(LONG);
typedef LONG (CALLBACK* LPFNDLLFUNC3)(LONG,CHAR *,CHAR *);
typedef LONG (CALLBACK* LPFNDLLFUNC4)(LONG,CHAR *,CHAR *);
typedef LONG (CALLBACK* LPFNDLLFUNC5)(LONG);
typedef LONG (CALLBACK* LPFNDLLFUNC6)();

extern LPFNDLLFUNC1 fnInitModem;
fnIniModem = NULL;
error C2501: 'fnIniModem' : missing storage-class or type specifiers



yimingsoft 2005-09-14
  • 打赏
  • 举报
回复
哈哈 我知道了 我的 函数写成局部的了
所以别的类里用不了
多谢你!
phoenix96_2000 2005-09-13
  • 打赏
  • 举报
回复
在xxx.h里面:
extern LPFNDLLFUNC1 fnInitModem;
xxx.h里面
LPFNDLLFUNC1 fnIniModem = NULL;

然后在某个全局函数里面初始化

其他的CPP就include "xxx.h"就可以了用了
fupingroot 2005-09-13
  • 打赏
  • 举报
回复
//取得函数地址
hInsDLL=LoadLibrary("MonDem");
if(hInsDLL==NULL){
ShowMessageNULL( IDS_LOADDLL_FAILED );
} else {
fnInitModem = (LPFNDLLFUNC1)GetProcAddress(hInsDLL,"fnInitModem");
fnCloseModem = (LPFNDLLFUNC2)GetProcAddress(hInsDLL,"fnCloseModem");
fnSendMsg = (LPFNDLLFUNC3)GetProcAddress(hInsDLL,"fnSendMsg");
fnReadMsgEx = (LPFNDLLFUNC4)GetProcAddress(hInsDLL,"fnReadMsgEx");


fnInitModem

fnCloseModem
fnSendMsg
这些函数是全局函数 。在.CPP中写的 我怎么在其他的类中引用啊?
fupingroot 2005-09-13
  • 打赏
  • 举报
回复
在其他的类中 ,fnInitModem()这个函数不认识啊?
phoenix96_2000 2005-09-13
  • 打赏
  • 举报
回复
就和函数调用一样使用
long lRetCode = fnInitModem(1);

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧