VC++和C++builder互相调用动态链接库DLL(VC++编的)笔记

关于动态链接库的具体介绍参考本人转载博客:进程间通信详解 - 动态链接库实现

下文说说自己编写的动态链接库,主要作用是实现用VC++编写的A程序和用C++builder编写的B程序之间的通信,其中涉及结构体,所以需要注意一下,

1>动态链接库myDLL

       新建一个dll工程(MFC AppWizard(dll)),并命名myDLL,这个工程中有三种形式:

               1.动态链接库和MFC静态链接
         2.动态链接库使用共享MFC DLL
                3.MFC扩展DLL(使用共享 MFC DLL)
       这三者的区别解释如下:静态dll中编译时嵌入了mfc的类文件,所以客户机上即使没有mfc的库文件也能运行你的dll,动态的dll运行时会调用系统的mfc库,所以客户机要想运行你的dll必须系统中必须有mfc库文件。常规mfc dll(前两种)不能导出类,只能导出函数,扩展的mfc dll则可以导出类。

         我在此选用了第二种,建完工程后,在myDLL.h中添加内容

// myDLL.h : main header file for the MYDLL DLL
//

#if !defined(AFX_MYDLL_H__C094CB0F_D564_446A_BEB7_FA2E437933BB__INCLUDED_)
#define AFX_MYDLL_H__C094CB0F_D564_446A_BEB7_FA2E437933BB__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

/
// CMyDLLApp
// See myDLL.cpp for the implementation of this class
//

 

//添加内容
#ifdef DLL_API
#else    
#define DLL_API extern "C" _declspec(dllexport)     注意1
#endif

typedef struct GongJianT
{
double h_X;
double h_Y;
double w_Z;
double w_XX;
double w_YY;
double w_ZZ;
}m_GongJianT;

DLL_API void SetData(double tmpData);
DLL_API double GetData();
DLL_API void SetSign(int msign);
DLL_API int  GetSign();
DLL_API void SetGJTData(m_GongJianT *m_GJT);
DLL_API void GetGJTData(m_GongJianT *m_GJT);

 

class CMyDLLApp : public CWinApp
{
public:
 CMyDLLApp();


// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CMyDLLApp)
 //}}AFX_VIRTUAL

 //{{AFX_MSG(CMyDLLApp)
  // 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()
};


/

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

#endif // !defined(AFX_MYDLL_H__C094CB0F_D564_446A_BEB7_FA2E437933BB__INCLUDED_)

 

在myDLL.cpp添加内容:

 

// myDLL.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "myDLL.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

 

#pragma data_seg("SharedDataInDll")    
//初始化为 0   
double data =0.0;
int Sign=0;
m_GongJianT m_GJT1={0.0,0.0,0.0,0.0,0.0,0.0};注意2,结构体必须初始化。
#pragma data_seg()

#pragma comment(linker, "/SECTION:SharedDataInDll,RWS")

//设置工件台数据
void SetGJTData(m_GongJianT *m_GJT)
{
 m_GJT1.h_X =m_GJT->h_X ;
 m_GJT1.h_Y =m_GJT->h_Y ;
 m_GJT1.w_Z =m_GJT->w_Z ;
 m_GJT1.w_XX=m_GJT->w_XX;
 m_GJT1.w_YY=m_GJT->w_YY;
 m_GJT1.w_ZZ=m_GJT->w_ZZ;

}
//返回工件台数据
void GetGJTData(m_GongJianT *m_GJT)
{
 m_GJT->h_X =m_GJT1.h_X ;
 m_GJT->h_Y =m_GJT1.h_Y ;
 m_GJT->w_Z =m_GJT1.w_Z ;
 m_GJT->w_XX=m_GJT1.w_XX;
 m_GJT->w_YY=m_GJT1.w_YY;
 m_GJT->w_ZZ=m_GJT1.w_ZZ;
}
//返回共享数据
double GetData()
{    return data;}
//设置共享数据
void SetData(double tmpData)
{data = tmpData;}
void SetSign(int msign)
{
 Sign=msign;
}
int GetSign()
{
 return Sign;
}
//
// Note!
//
//  If this DLL is dynamically linked against the MFC
//  DLLs, any functions exported from this DLL which
//  call into MFC must have the AFX_MANAGE_STATE macro
//  added at the very beginning of the function.
//
//  For example:
//
//  extern "C" BOOL PASCAL EXPORT ExportedFunction()
//  {
//   AFX_MANAGE_STATE(AfxGetStaticModuleState());
//   // normal function body here
//  }
//
//  It is very important that this macro appear in each
//  function, prior to any calls into MFC.  This means that
//  it must appear as the first statement within the
//  function, even before any object variable declarations
//  as their constructors may generate calls into the MFC
//  DLL.
//
//  Please see MFC Technical Notes 33 and 58 for additional
//  details.
//

/
// CMyDLLApp

BEGIN_MESSAGE_MAP(CMyDLLApp, CWinApp)
 //{{AFX_MSG_MAP(CMyDLLApp)
  // 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
END_MESSAGE_MAP()

/
// CMyDLLApp construction

CMyDLLApp::CMyDLLApp()
{
 // TODO: add construction code here,
 // Place all significant initialization in InitInstance
}

/
// The one and only CMyDLLApp object

CMyDLLApp theApp;

编译后便可生成myDLL.dll和myDLL.lib文件。

 

以后的过程就开始用A程序和B程序进行调用,

 

     1、用extern "C"修饰VC导出的DLL函数。如:extern "C" __declspec(dllimport) int aFunc(int a);
     2、用C++Builder的implib工具生成DLL对应的lib文件。如:implib xx.lib xxx.dll。生成lib文件之后,C++Builder便可以使用这个lib文件了。

 

 

2>   VC++编写的A程序需要添加的文件:

ShareDll.h

 

#ifndef SHARED_DLL
#define SHARED_DLL
//在 DLL 项目中设置 DLL_API 为导出类型 extern "C" _declspec(dllimport)
//在 Test 项目中则无需设置该 DLL_API , 直接使用这个 CalculateDLL.h 文件即可
#ifdef DLL_API
#else    
#define DLL_API extern "C" _declspec(dllimport)
#endif

typedef struct GongJianT
{
double h_X;
double h_Y;
double w_Z;
double w_XX;
double w_YY;
double w_ZZ;
}m_GongJianT;

DLL_API void SetData(int tmpData);
DLL_API int GetData();

DLL_API void SetGJTData(m_GongJianT *m_GJT);
DLL_API void GetGJTData(m_GongJianT *m_GJT);
#endif

 

在需要调用动态链接库的源文件中需要添加:

#include "ShareDLL.h"

#pragma comment(lib, "myDLL.lib")

 

 

3>    C++builder编写的B程序中需添加:

ShareDll.h

 

#ifndef SHARED_DLL
#define SHARED_DLL
//在 DLL 项目中设置 DLL_API 为导出类型 extern "C" _declspec(dllimport)
//在 Test 项目中则无需设置该 DLL_API , 直接使用这个 CalculateDLL.h 文件即可
#ifdef DLL_API
#else    
#define DLL_API extern "C" _declspec(dllimport)
#endif

typedef struct GongJianT
{
double h_X;
double h_Y;
double w_Z;
double w_XX;
double w_YY;
double w_ZZ;
}m_GongJianT;

DLL_API _stdcall void SetData(int tmpData);
DLL_API _stdcall int GetData();

DLL_API _stdcall void SetGJTData( m_GongJianT *m_GJT);
DLL_API _stdcall void GetGJTData( m_GongJianT *m_GJT);注意3,和A程序中的不同
#endif

 

在使用动态链接库中函数的源文件中需添加

#include "ShareDLL.h"

#pragma comment(lib, "bcb.lib")        //bcb.lib是通过implib bcb.lib myDLL.dll命令生成的,  

 

 

注意:myDLL.dll  myDLL.lib   bcb.lib 需要包含在用到它的程序中

 

 

你可能感兴趣的:(C++/C)