[ 前言]

         网上用很多关于MFC 共享DLL的简介,此处不在叙述。实际应用中发现"共享MFC DLL的规则DLL"是在编写基于MFC的DLL程序时,编译后该DLL中不包含MFC的库的一种DLL 库文件。这种方式比"带静态链接MFC的规则DLL"编译的稍微大些。因此,当发布"共享MFC DLL的规则DLL"dll时,如果对方的机器上没有安装MFC的库,那么该dll是运行不了的,除非你将MFC的库也一块给他,"共享MFC DLL的规则DLL"和"带静态链接MFC的规则DLL"最大的区别就是在使用MFC的方法上。
正是由于"共享MFC DLL的规则DLL"的这些特点,导致在系统加载该类dll时,会涉及到多个dll的加载,那么如果当DLL和应用程序中存在相同ID的资源时,系统不能正确分辨程序员的意图,因此,使用"共享MFC DLL的规则DLL"我们需要通过模块切换来找到正确的资源模块,并进行对应的操作。
"共享MFC DLL的规则DLL"的模块切换:
再说明这个问题之前,我们先来了解下DLL的内部运行机制:

应用程序进程本身及其调用的每个DLL模块都具有一个全局唯一的HINSTANCE句柄,它们代表了DLL或EXE模块在进程虚拟空间中的起始地址。进程本身的模块句柄一般为0x400000,而DLL模块的缺省句柄为0x10000000。如果程序同时加载了多个DLL,则每个DLL模块都会有不同HINSTANCE。          应用程序在加载DLL时对其进行了重定位。共享MFC DLL(或MFC扩展DLL)的规则DLL涉及到HINSTANCE句柄问题,HINSTANCE句柄对于加载资源特别重要。EXE和DLL都有其自己的资源,而且这些资源的ID可能重复,应用程序需要通过资源模块的切换来找到正确的资源。

      如果应用程序需要来自于DLL的资源,就应将资源模块句柄指定为DLL的模块句柄;如果需要EXE文件中包含的资源,就应将资源模块句柄指定为EXE的模块句柄。

        为了完成模块切换,在所有从DLL输出的函数中都应该使用以下语句开头:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
      此句话用来正确切换MFC的模块状态。说明: 其功能是在栈上(这意味着其作用域是局部的)创建一个AFX_MODULE_STATE类的实例,并将其指针pModuleState返回。 AFX_MODULE_STATE类利用其构造函数和析构函数进行存储模块状态现场及恢复现场的工作。

该宏用于将pModuleState设置为当前的有效模块状态。当离开该宏的作用域时(也就离开了pModuleState所指栈上对象的作用域),先前的模块状态将由类AFX_MODULE_STATE的析构函数恢复。

(2)带静态链接MFC的规则DLL;

这个不多讲,是将MFC dll编译到自身内部的DLL类型,对比"使用共享MFC DLL的规则DLL"不难理解;

(3)规则DLL中的调用约定和名称修饰:
调用约定是程序向函数传递参数,以及接收返回值的标准约定,它是为了实现函数调用而建立的一种标准的协议,这种协议规定了该语言的函数中的参数传递方法,参数是否可变以及由谁来处理堆栈等问题,不同的语言定义了不同的调用约定。
在C++中,为了允许操作符重载和函数重载,C++编译器往往按照某种规则改写每一个入口点的符号名,以便允许同一个名字(具有不同的参数类型或者是不同的作用域)有多个用法,而不会打破现有的基于C的链接器.这项技术通常被称为名称改编(Name Mangling)或者名称修饰(Name Decoration).许多C++编译器厂商选择了自己的名称修饰方案.
因此,为了使其它语言编写的模块(如Visual Basic应用程序、Pascal或Fortran的应用程序等)可以调用C/C++编写的DLL的函数,必须使用正确的调用约定来导出函数,并且不要让编译器对要导出的函数进行任何名称修饰.
调用约定用来处理决定函数参数传送时入栈和出栈的顺序(由调用者还是被调用者把参数弹出栈),以及编译器用来识别函数名称的名称修饰约定等问题.在Microsoft VC++ 6.0中定义了下面几种调用约定:

1,__cdecl
__cdecl是C/C++和MFC程序默认使用的调用约定,也可以在函数声明时加上__cdecl关键字来手工指定.采用__cdecl约定时,函数参数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈.因此,实现可变参数的函数只能使用该调用约定.由于每一个使用__cdecl约定的函数都要包含清理堆栈的代码,所以产生的可执行文件大小会比较大.__cdecl可以写成_cdecl
2、__stdcall
__stdcall调用约定用于调用Win32 API函数.采用__stdcal约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定.由于函数体本身知道传进来的参数个数,因此被调用的函数可以在返回前用一条ret n指令直接清理传递参数的堆栈.__stdcall可以写成_stdcall
3、__fastcall
__fastcall约定用于对性能要求非常高的场合.__fastcall约定将函数的从左边开始的两个大小不大于4个字节(DWORD)的参数分别放在ECX和EDX寄存器,其余的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的堆栈.__fastcall可以写成_fastcall. 
        最后说明:关键字
__cdecl__stdcall__fastcall可以直接加在要输出的函数前,也可以在编译环境的Setting...->C/C++->Code Generation项选择.它们对应的命令行参数分别为/Gd、/Gz和/Gr.缺省状态为/Gd,即__cdecl.当加在输出函数前的关键字与编译环境中的选择不同时,直接加在输出函数前的关键字有效. 

   从上面看出MFC 共享DLL是一个非常复杂的工程,关于MFC dll的相关知识很多很杂,对于他的学习只能在实践中慢慢去摸索。最大的感触就是它不同于"MFC扩展DLL",在规则DLL中内部虽然是可以使用MFC,但是规则DLL的接口应该不能是基于MFC的。而MFC扩展DLL与应用程序接口可以是MFC,可以从MFC扩展dll中导出一个MFC的派生类。

        一般情况下我们都会使用规则的dll,因为"规则DLL"能够提供给所有支持dll技术的语言的调用接口。在规则DLL中,有一个CWinApp继承下来的类,dll入口函数则是由MFC自动提供,被MFC封装。此类DLL程序从CWinApp派生,但是没有消息循环。

        动态链接到MFC 的规则DLL 可以和使用它的可执行文件同时动态链接到 MFC DLL 和任何MFC扩展 DLL。在使用了MFC共享库的时候,默认情况下,MFC使用主应用程序的资源句柄来加载资源模板。这样,当DLL和应用程序中存在相同ID的资源时(即 所谓的资源重复问题),系统可能不能获得正确的资源。因此,对于共享MFC DLL的规则DLL,我们必须进行模块切换以使得MFC能够找到正确的资源模板。

        我们可以在Visual C++中设置MFC规则DLL是静态链接到MFC DLL还是动态链接到MFC DLL。如图8,依次选择Visual C++的project -> Settings -> General菜单或选项,在Microsoft Foundation Classes中进行设置。

[ MFC 规则DLL 封装库实例] 

[第一步] 打开VS 2019如下图所示。点击“创建新项目(N)”进入项目创建窗口。

[第二步] 在要创建的项目属性中选择“MFC动态链接库”,点击“下一步”继续。

[第三步] 在项目名称中输入要新建的项目名称,本例以“MFC_Dll_Test”为例进行演示。 点击“创建”按钮进行项目创建。

[第四步] 在DLL类型中选择"使用共享MFC DLL的常规DLL"后点击“确定”按钮

[第五步] 新建完成后弹出如下窗口,如下图所示可以看到项目的头文件及其源文件以及资源文件。

[第六步] 打开项目的资源文件,在资源文件中插入一个对话框,并将对话框的ID修改为:IDD_DIALOGTEST。在对话框上增加一个 Text Control控件,并将ID修改为IDC_STATICTEST。用同样的方法增加2个按钮ID分别为:IDC_BUTTON1IDC_BUTTON2。如下图所示,并为以上三个控件增加变量,变量分别为:m_TextTest、m_ButtonTestOne、m_ButtonTestTwo

[第七步] 将对话框中要用到的类和头文件拷贝到“MFC_Dll_Test”MFC DLL 工程所在的文件夹下如下图所示。本例程用到两个类一个是“CMyButton”一个是“OwnerDrawStatic”类和一个头文件“MacroDefinition”。CMyButton类包含CMyButton.h头文件和CMyButton.CPP源文件。OwnerDrawStatic类包含OwnerDrawStatic.h头文件和OwnerDrawStatic.CPP源文件。“MacroDefinition”是一个宏定义头文件。

[第八步] 在项目的解决方案管理器中将头文件“MacroDefinition”包含到项目中。如下图所示。

[第九步] 在类向导中将“CMyButton”类和“OwnerDrawStatic”添加到项目中。如下图所示。

[第十步] 完成以上操作后,为MFC_Dll_Test项目中插入的对话框IDD_DIALOGTEST添加类文件,本文类文件名为“CMfcDellDlg”,并在“CMfcDellDlg.h”头文件中包含新添加的两个类的头文件“CMyButton.h”类和“OwnerDrawStatic.h”。如下图所示。并将三个控件变量m_TextTest、m_ButtonTestOne、m_ButtonTestTwo。的类型分别替换为CMyStaticCMyButton。值得说明的是CMyStatic类是一个继承于CStatic类的继承类,是对CStatic类的重写。CMyButton类是一个继承于CButton类的继承类,是对CMyButton类的重写。

[第十一步] 在对话框类的CMfcDellDlg.CPP中重载OnInitDialog()OnClose()函数,并在OnInitDialog函数内增加以下代码。在"CMfcDellDlg.h"中增加自定义消息#define WM_SHUNTDOWN       WM_USER+100,OnClose()增加如下代码。

#define WM_SHUNTDOWN       WM_USER+100
void CMfcDellDlg::OnClose()
{// TODO: 在此添加消息处理程序代码和/或调用默认值m_Parent->PostMessage(WM_SHUNTDOWN);CDialog::OnClose();
}
BOOL CMfcDellDlg::OnInitDialog()
{CDialog::OnInitDialog();m_TextTest.SetWindowText(_T("Hello Word This is a MFC Dell Test Demo"));m_TextTest.SetTextFont(18, FALSE, TRUE, L"Times New Roman");m_TextTest.m_SetBkColor(RGB(0, 0, 255));m_TextTest.m_SetTextClr(RGB(243, 249, 241));this->SetWindowText(_T("MFC_DLL_TEST_DEMO"));m_ButtonTestOne.SetTextFont(CONTROLBUTTON_FONT_HEIGHT, FALSE, FALSE, CONTROLBUTTON_FACENAME);m_ButtonTestTwo.SetTextFont(CONTROLBUTTON_FONT_HEIGHT, FALSE, FALSE, CONTROLBUTTON_FACENAME);m_ButtonTestOne.SetWindowText(_T("TestOne"));m_ButtonTestTwo.SetWindowText(_T("TestTwo"));return TRUE;
}

[第十二步] 在MFC DLL工程的头文件“MFC_Dll_Test.h”中增加一个全局函数ShowMfcDellDlg(),如下图所示。

extern "C" _declspec(dllexport) CMfcDellDlg* ShowMfcDellDlg(CWnd * pParent);
// MFC_Dll_Test.h: MFC_Dll_Test DLL 的主标头文件
//
#include"CMfcDellDlg.h"
#pragma once#ifndef __AFXWIN_H__#error "在包含此文件之前包含 'pch.h' 以生成 PCH"
#endif#include "resource.h"       // 主符号// CMFCDllTestApp
// 有关此类实现的信息,请参阅 MFC_Dll_Test.cpp
//class CMFCDllTestApp : public CWinApp
{
public:CMFCDllTestApp();// 重写
public:virtual BOOL InitInstance();DECLARE_MESSAGE_MAP()virtual int ExitInstance();
};
extern "C" _declspec(dllexport) CMfcDellDlg* ShowMfcDellDlg(CWnd * pParent);

[第十三步] 在MFC DLL工程的源文件“MFC_Dll_Test.CPP”实现第十二步增加的函数ShowMfcDellDlg()。 如下图所示本例程生成的DLL包含的对话框采用非模态调用的方式调用,模态方式调用和非模态方式调用的差别较大函数中“pParent”变量的作用主要是封装后的DLL中的对话框在其被他项目调用时能取得主窗口的基类,并通过参数来使用基础类库中所有窗口类的基本功能。注意函数中的AFX_MANAGE_STATE(AfxGetStaticModuleState());

AFX_MANAGE_STATE(AfxGetStaticModuleState())

AFX_MANAGE_STATE(AfxGetStaticModuleState());//用于模块切换时的状态保护,

        1.AfxGetStaticModuleState()指向当前模块状态;

        2.当前函数调用结束后原模块的状态自动被恢复;

        3.用于DLL中所调用MFC函数、类、资源时的模块状态切换

AFX_MANAGE_STATE的作用切换到指定的Module State,当出了作用域的时候将Module State恢复到原来的值。是在不同的Module State之中切换,原因有2:

        1.在不同的MFC DLL和MFC EXE的Module State之间切换,保持正确的AFX_MODULE_STATE,最常见的问题是在DLL输出的函数之中无法获得DLL本身相关的资源,这就是没有正确维护Module State的原因造成的,因为当前Resource DLL的句柄就保存在Module State之中。

        2.切换Activation Context,不同的Module必然有着不同的Activation Context,需要切换。
一般的用法如下:

void SomeMFCDllFunction()

{

AFX_MANAGE_STATE(AfxGetStaticModuleState())


注意这里使用的是AfxGetStaticModuleState,而非AfxGetModuleState。原因是在DLL项目中,AfxGetStaticModuleState返回的是DLL本身的Module State,而AfxGetModuleState则是返回当前线程相关的Module State,由于一般DLL输出的函数是被其他Module调用,那么大部分情况下当前线程的Module State都是错误的,所以必须得使用DLL本身的Module State。

[CSDN中对AFX_MANAGE_STATE的介绍]

 动态链接到 MFC 的规则 DLL 是在内部使用 MFC 的 DLL,这类 DLL 中的导出函数可由 MFC 或非 MFC 可执行文件调用。正如名称所体现的,这类 DLL 是使用 MFC 动态链接库版本(也称作 MFC 共享版本)生成的。函数通常是通过标准 C 接口从规则 DLL 导出的。

在动态链接到 MFC 的规则 DLL 中,必须在所有导出函数的开始处添加 AFX_MANAGE_STATE 宏,以将当前模块的状态设置为 DLL 的状态。为此,需将下列代码行添加到从 DLL 导出的函数的开始处:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

动态链接到 MFC 的规则 DLL 具有下列功能:

  • 它是由 Visual C++ 4.0 引入的一种新的 DLL 类型。

  • 客户端可执行文件可以用任何支持使用 DLL 的语言(C、C++、Pascal、Visual Basic 等)编写;它不必是 MFC 应用程序。

  • 与静态链接的规则 DLL 不同,这类 DLL 动态链接到 MFC DLL(也称作共享 MFC DLL)。

  • 链接到这类 DLL 的 MFC 导入库与用于使用 MFC DLL 的扩展 DLL 或应用程序的 MFC 导入库相同:都是 MFCxx(D).lib。

动态链接到 MFC 的规则 DLL 具有下列要求:

  • 与动态链接到 MFC DLL 的可执行文件相同,这些 DLL 也是通过定义的 _AFXDLL 进行编译的。但同时也像静态链接到 MFC 的规则 DLL 那样,定义了 _USRDLL。

  • 这类 DLL 必须实例化 CWinApp 派生类。

  • 此类型的 DLL 使用 MFC 提供的 DllMain。与在标准 MFC 应用程序中一样,将所有 DLL 特定的初始化代码放到 InitInstance 成员函数中,将终止代码放到 ExitInstance 中。

由于这类 DLL 使用 MFC 动态链接库版本,因此必须将当前模块的状态显式设置为 DLL 的状态。为此,请在从 DLL 导出的每个函数的开始处使用 AFX_MANAGE_STATE 宏。

与 MFC 应用程序相同,规则 DLL 必须有一个 CWinApp 派生的类和此应用程序类的单个对象。然而,与应用程序的 CWinApp 对象不同,DLL 的 CWinApp 对象没有主消息泵。

请注意,CWinApp::Run 机制不适用于 DLL,因为应用程序拥有主消息泵。如果 DLL 生成无模式对话框或有自己的主框架窗口,则应用程序的主消息泵必须调用从 DLL 导出的例程来调用 CWinApp::PreTranslateMessage。

与在标准 MFC 应用程序中一样,将所有 DLL 特定的初始化放到 CWinApp::InitInstance 成员函数中。卸载 DLL 之前,将从 MFC 提供的 DllMain 函数调用 CWinApp 派生类的 CWinApp::ExitInstance 成员函数。

必须随应用程序一起发布共享 DLL:MFCx0.dll 和 Msvcr*0.dll(或类似的文件)。

动态链接到 MFC 的 DLL 无法同时静态链接到 MFC。像任何其他 DLL 一样,应用程序链接到动态链接到 MFC 的规则 DLL。

符号通常是通过标准 C 接口从规则 DLL 导出的。从规则 DLL 导出的函数的声明类似下面这样:

extern "C" __declspec(dllexport) MyExportedFunction( );

规则 DLL 内的所有内存分配都应在该 DLL 内进行;DLL 不应向调用可执行文件传递或从调用可执行文件接收下列任何指针:

  • 指向 MFC 对象的指针

  • 指向由 MFC 分配的内存的指针

如果需要执行上述任一操作,或者如果需要在调用可执行文件和 DLL 之间传递 MFC 派生的对象,则必须生成扩展 DLL。

仅当创建了数据副本后,在应用程序和 DLL 之间传递指向 C 运行时库所分配的内存的指针才是安全的。一定不要删除这些指针或调整它们的大小,也不要在没有创建内存副本的情况下使用这些指针。

生成动态链接到 MFC 的规则 DLL 时,需要使用 AFX_MANAGE_STATE 宏正确切换 MFC 模块状态。为此,需将下列代码行添加到从 DLL 导出的函数的开始处:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

AFX_MANAGE_STATE 宏不应当用于静态链接到 MFC 的规则 DLL 中,也不应当用于扩展 DLL 中。有关更多信息,请参见管理 MFC 模块的状态数据。

extern "C" _declspec(dllexport)  CMfcDellDlg * ShowMfcDellDlg(CWnd * pParent)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());CMfcDellDlg* Dlg;Dlg = new CMfcDellDlg(pParent);Dlg->Create(IDD_DIALOGTEST, NULL);Dlg->ShowWindow(SW_SHOWNORMAL);Dlg->CenterWindow();return Dlg;
}

[第十四步]完成上述工作后编译“MFC_Dll_Test”项目,编译成功后在项目文件夹Release文件下会出现已经编辑完成的MFC_Dll_Test.DLL文件和MFC_Dll_Test.LIB文件.如下图所示。

[第十五步]新建一个MFC对话框工程,本文已上一讲中建立好的项目“MFCApplication1Dlg”为例子进行说明。新建MFC对话框类工程(MFCApplication1)用于测试封装完成的类是否正确,能否正常使用。在工程文件下新建“Cbinclude”文件夹用于存放DLL库文件的MFC_Dll_Test.h头文件,新建Cblib”文件夹用于存放MFC_Dll_Test.Lib库文件。将“MFC_Dll_Test.dll”文件分别放入项目文件夹下的"Debug""Release"文件夹下。如下图所示。

[第十六]在项目属性中打开“MFCApplication1”项目属性对话框如下图所示。

 [第十七步]在项目属性中打开“MFCApplication1”项目属性对话框如下图所示。选中“C/C++”属性,在右边的“附加包含目录”中选择“Cbinlude”文件夹所在的目录,并在"连接器"选项中配置"Cblib"库文件所在的目录,具体配置方式可以参考上一讲的类容这里不在描述。

 [第十八步]配置完成后将“MFC_Dll_Test”MFC DLL项目中生成的“MFC_Dll_Test.lib”文件复制到“MFCApplication1”项目文件夹下的“Cblib”文件夹中。将“MFC_Dll_Test.dll”文件复制到“MFCApplication1”项目文件夹下的“Debug”和“Release”文件夹中。将所有要用到的头文件复制到“MFCApplication1”项目文件夹下的“Cbinlude”文件夹中。如下图所示。

 [第十九步]在项目“MFCApplication1Dlg.h”头文件中包含"CMyStatic.h"头文件和
"
MFC_Dll_Test.h"。在类向导中为对话框添加自定义消息处理函数。如下图所示。并在消息处理函数中增加如下代码。并重载"OnClose()"函数,并增加响应代码。

afx_msg LRESULT CMFCApplication1Dlg::OnShuntdown(WPARAM wParam, LPARAM lParam)
{if (NULL!= m_Dlg){delete m_Dlg;m_Dlg = NULL;}if (NULL != hDll){FreeLibrary(hDll);hDll = NULL;}return 0;
}
oid CMFCApplication1Dlg::OnClose()
{if (NULL!= m_Dlg){delete m_Dlg;m_Dlg = NULL;}if (NULL!= hDll){FreeLibrary(hDll);hDll = NULL;}CDialogEx::OnClose();
}

[第二十步]在项目对话框中添加一个按钮。将按钮的ID改为“IDC_BUTTONTESTMFCDELL

并为按钮增加处理函数。

[第二十一步]在"MFCApplication1Dlg.h"头文件中包含“MFC_Dll_Test.h”并在其中定义两个变量CMfcDellDlg* m_Dlg;HINSTANCE hDll;  


// MFCApplication1Dlg.h: 头文件
#include"CMyStatic.h"
#include"MFC_Dll_Test.h"
#pragma once// CMFCApplication1Dlg 对话框
class CMFCApplication1Dlg : public CDialogEx
{
// 构造
public:CMFCApplication1Dlg(CWnd* pParent = nullptr);   // 标准构造函数// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_MFCAPPLICATION1_DIALOG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
public:afx_msg void OnBnClickedOk();CMfcDellDlg* m_Dlg;HINSTANCE hDll;   //DLL句柄  //CMyStatic m_statictext;CMyStatic m_idcttt;afx_msg void OnBnClickedButtontestmfcdell();afx_msg void OnClose();
protected:afx_msg LRESULT OnShuntdown(WPARAM wParam, LPARAM lParam);
};

[第二十二步]在"MFCApplication1Dlg.CPP"中按钮事件函数中增加调用MFC DLL库的功能函数。

void CMFCApplication1Dlg::OnBnClickedButtontestmfcdell()
{hDll = LoadLibrary(_T("MFC_Dll_Test.dll"));  //加载dllif (NULL == hDll){MessageBox(_T("MFC_Dll_Test动态链接库加载失败!"));return;}typedef CMfcDellDlg* (*lpCallDell)(CWnd*);lpCallDell MfcDlg = (lpCallDell)GetProcAddress(hDll,"ShowMfcDellDlg");if (MfcDlg==NULL){FreeLibrary(hDll);MessageBox(_T("ShowMfcDellDlg函数加载失败!"));return;}if (NULL==m_Dlg){m_Dlg = MfcDlg(this);}else if (NULL!= m_Dlg){MessageBox(_T("对话框已成功加载,请关闭后再试!"),_T("信息提示"),MB_ICONINFORMATION|MB_OKCANCEL);return;}
}

如果不对hDll进行判断的话每点击一次按钮就会调用一次MFC DLL导致出现多个窗口。如下图所示。

进行判断后对话框关闭后会向调用窗口发送“WM_SHUNTDOWN”以便主窗口进行资源释放。更改之后更加灵活。运行效果如下图所示。

         详细例程已上传到资源,可供参考。DLL是一个相当复杂的系统工程只能在碎片中慢慢学习和积累,下一篇将会对win32 dll封装的步骤进行详细的研究。

https://download.csdn.net/download/lzc881012/86400621https://download.csdn.net/download/lzc881012/86400621

VS2019 MFC DLL共享动态链接库(MFC 常规库)封装例程非模态调用 MFC 常规库[二]相关推荐

  1. c++封装so库,供安卓android调用

    文章目录 一.概述 二.用C/C++开发出Linux的so库 1.开发分析: 2.开发准备: 三.在C/C++代码里加入JNI,支持java通过JNI调用so库 1.JNI 是Java Native ...

  2. MFC模块的动态链接库DLL以及静态链接库LIB编译后的调用

    静态链接库LIB和动态链接库DLL的区别,创建和示例   1.什么是静态连接库,什么是动态链接库   静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都 ...

  3. VC++动态链接库编程之MFC DLL

    1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量.函数或类.在仓库的发展史上经历了" ...

  4. VC++动态链接库(DLL)编程(二)--非MFC DLL

    4.非MFC DLL 4.1一个简单的DLL 第2节给出了以静态链接库方式提供add函数接口的方法,接下来我们来看看怎样用动态链接库实现一个同样功能的add函数. 如图6,在VC++中new一个Win ...

  5. VC++ MFC DLL动态链接库编写详解

    虽然能用DLL实现的功能都可以用COM来替代,但DLL的优点确实不少,它更容易创建.本文将讨论如何利用VC MFC来创建不同类型的DLL,以及如何使用他们. 一.DLL的不同类型 使用VC++可以生成 ...

  6. Visual Studio如何实现.exe免安装免DLL运行[动态链接库--->>>静态链接库]

    Visual Studio如何实现.exe免安装免DLL运行[动态链接库--->>>静态链接库] 前言 一. 什么是程序库? 1. 静态库: 2. 动态库: 3. 两者区别: 二. ...

  7. 孙鑫-MFC笔记十一--动态链接库

    Windows三个重要的动态链接库 Kernel32.dll,它包含用于管理内存.进程和线程的各个函数: User32.dll,它包含用于执行用户界面任务(如窗口的创建和消息的传送)的各个函数: GD ...

  8. 三.MFC DLL窗口的创建和注入显示

    一.什么是MFC 微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windo ...

  9. linux动态链接库全局变量共享问题DLL共享数据段

    Linux写时拷贝技术(copy-on-write) 进程间是相互独立的,其实完全可以看成A.B两个进程各自有一份单独的liba.so和libb.so,相应的动态库的代码段和数据段都是各个进程各自有一 ...

最新文章

  1. python买什么书好-python看什么书好
  2. python实训报告pygame_[源码和文档分享]基于Python的PyGame库实现的2048小游戏
  3. directshow+opencv显示usb的摄像头代码(并保存视频中的图片)
  4. (chap4 Http状态码) 5XX
  5. 电脑声音推送到手机话筒_一台电脑是不是就能做在线教育直播了?
  6. DRF数据验证+数据存储
  7. kalman滤波在雷达目标跟踪中的应用_简述Automotive radar中的多目标跟踪处理
  8. 多个数据文件 mysql_mysql多实例(多个配置文件方式)
  9. 关闭linux系统中读写页缓存,Linux文件系统FAQ
  10. 『转载』看c#打印的各种技术
  11. 整车开发过程通用英文缩写
  12. 高仿京东分类页面实现
  13. Cisco Packet Tracer 实验
  14. 富爸爸实现财务自由七步骤
  15. python 批处理合并表格_高效办公4——Python批量合并Excel指定列相同内容单元格...
  16. liunx下载安装JDK1.8教程
  17. 单例(Singleton)设计模式
  18. 霍尔 磁电 光电式传感器的比较 实验思考题
  19. This Exception was thrown from a job compiled with Burst, which has limited exception support. 报错
  20. 访问github时出现隐私设置错误您的连接不是私密连接问题的解决方案

热门文章

  1. 群晖aria2 bt没速度_当苹果用户拥有NAS后可以做什么?群晖DS220J体验测评
  2. 全国计算机技术与软件专业技术资格(水平)考试报名时间 上半年2023年3月13日开始,下半年2023年8月14日开始
  3. 上周技术关注:函数式编程另类指南
  4. 没办法计算机快捷键,快捷键Ctrl+Shift无法切换输入法没响应的解决办法
  5. 装饰者设计模式(java版本)
  6. JAVA中的常见Bug
  7. jdk历史版本下载地址
  8. Cool JavaScript Tricks
  9. Cool Number
  10. 【JavaScript】【5】定时器(包含回调函数与Promise)