C++ dll调用-动态(显式)

C++ dll调用-动态(显式)

废话不说上代码, dll 头文件 j_test.h
#pragma once
extern "C"_declspec(dllexport) void maopao(int *p, int count);
extern "C"_declspec(dllexport) int test(int *p, char* count);
extern "C"_declspec(dllexport) int sum(int  i1,  int  i2);
class j_test
{

public:
    j_test();
    ~j_test();
    void maopao(int *p, int count);
    int sum(int  i1, int  i2);
    int test(int *p, char* count);
};

dll 实现类  j_test.cpp

#include "j_test.h"

j_test::j_test()
{
}

j_test::~j_test()
{
}

void maopao(int *p, int count)
{
    int temp = 0;
    for (int i = 1; i<count; i++)
    {
        for (int j = count - 1; j >= i; j--)
        {
            if (p[j]>p[j - 1])
            {
                temp = p[j];
                p[j] = p[j - 1];
                p[j - 1] = temp;
            }
        }
    }
}

int test(int *p, char* count){
    count[0] = (char)p[0];
    count[1] = (char)p[1];
    return 0;
}
int sum(int  i1, int  i2){

    return i1 + i2;
}

调用方 头文件

goo.h
#pragma once
class goo
{
public:
    goo();
    ~goo();
    void main(void);
};
goo.cpp
#include "goo.h"

goo::goo()
{
}

goo::~goo()
{
}

#include<iostream>
#include<Windows.h>
#include<time.h>
typedef int(*Dllfun)(int *, int);
typedef int(*TestFun)(int *, char *);
typedef int(*SumFun)(int  , int  );
using namespace std;
int main()
{
    Dllfun maopao1;
    HINSTANCE hdll;
    hdll = LoadLibrary("F:/workspaces/visual studio 2013/Projects/project-1/Project1/Debug/Project1.dll");
    if (hdll == NULL)
    {
        FreeLibrary(hdll);
    }
    maopao1 = (Dllfun)GetProcAddress(hdll, "maopao");
    if (maopao1 == NULL)
    {
        FreeLibrary(hdll);
    }
    int a[10];
    srand(time(0));
    for (int i = 0; i<10; i++)
        a[i] = rand() % 50;
    maopao1(a, 10);
    for (int i = 0; i<10; i++)
        cout << a[i] << endl;
    int b;
    char cs[10];
    TestFun testFun = (TestFun)GetProcAddress(hdll, "test");
    b = testFun(a, cs);
    cout << "cs = .............."  << endl;
    for (int i = 0; i<10; i++)
        cout << cs[i] << endl;
    cout << "b=" << b << endl;

    cout << "sumFun = .............." << endl;
    SumFun  sumFun = (SumFun)GetProcAddress(hdll, "sum");
    b = sumFun(3, 4);
    cout << "b=" << b << endl;

    cin >>  b;

    FreeLibrary(hdll);

}

C++如何调用DLL呢,有两种,一种是静态,另外一种是动态,即通过调用windowsAPI 来加载和卸载DLL,具体思路:

1.先编写一个DLL, 可以没有单独的头文件,因为很多情况下的DLL都是没有和lib和头文件一起的。

2.然后另外新建一个项目,来调用DLL,方法是:

1.声明头文件<windows.h>,说明我想用windows32方法来加载和卸载DLL

2.然后用typedef定义一个指针函数类型.typedef  void(*fun) //这个指针类型,要和你调用的函数类型和参数保持一致,记住,是指针参数就是(int *,int)

3.定一个句柄实例,用来取DLL的实例地址。HINSTANCE hdll;

格式为hdll=LoadLibrary(“DLL地址”);这里字符串类型是LPSTR,当是unicode字符集的时候会不行,因此要在配置-属性-常规里面把默认字符集“unicode”改成支持多字符扩展即可。

4.取的地址要判断,返回的句柄是否为空,如果为无效句柄,那么要释放加载DLL所占用的内存。

FreeLibrary(hdll);

5.然后定义一个函数指针,用来获取你要用的函数地址,这个咋用呢?

先是定一个函数指针 fun FUN;然后通过GetProcAdress来获取函数的地址,这个函数参数是什么呢?

参数是DLL的句柄和你要调用的函数名:比如:FUN=(fun)GetProcAdress(hdll,"sum");

这里也要判断要函数指针是否为空,如果没取到要求的函数,那么要释放句柄

FreeLibrary(hdll);

6.然后通过函数指针来调用函数。

FUN(int *p,int count);这里不能用函数名来使用函数,因为这个DLL本身不是当前CPP的一部分,而是通过windows去调用.没有在这个工程里声明或者定义,而是暴露出一个头,要指针获取他的地址,通过指针来调用.

最后调用结束后,就释放句柄

FreeLibrary(hdll);

这里只是通过动态加载没有涉及到静态的。这个在后续会学习。

 

来自 :   http://www.cnblogs.com/lhbssc/archive/2012/02/08/2342853.html

时间: 2024-10-21 23:29:52

C++ dll调用-动态(显式)的相关文章

QT创建与调用Dll方法(包括类成员)--显式调用

看网上的好多关于QT调用Dll的方法,大部分都是调用函数的,并没有调用C++类成员的情况,即使是有,比如说: 使用Qt编写模块化插件式应用程序 Qt 一步一步实现dll调用(附源码)---(这一篇里没有调用类成员的) Qt调用dll中的功能函数 ?我就是按照这上面的教程一步步做的,可惜了都没成功~~~这里面都有一个最重要的步骤没有说清楚(可能怪我笨~~),路径问题!!! 所以这里自我做一下总结: 创建时选择C++ Library就可以了,然后选择Shared Library(共享库),其他默认O

Windows提供了两种将DLL映像到进程地址空间的方法(隐式和显式)

调用DLL,首先需要将DLL文件映像到用户进程的地址空间中,然后才能进行函数调用,这个函数和进程内部一般函数的调用方法相同.Windows提供了两种将DLL映像到进程地址空间的方法: 1. 隐式的加载时链接 这种方法需要DLL工程经编译产生的LIB文件,此文件中包含了DLL允许应用程序调用的所有函数的列表,当链接器发现应用程序调用了LIB文件列出的某个函数,就会在应用程序的可执行文件的文件映像中加入一些信息,这些信息指出了包含这个函数的DLL文件的名字.当这个应用程序运行时,也就是它的可执行文件

Dll的编写与Dll的显示调用和隐式调用

Dll的编写: 现在新建的Dll工程中创建一个新的类,我在这个类中简单定义了Add, Substract, Mutiply, Divide这4个方法 具体代码如下:(MathFuncs.h) #pragma once #ifndef _MathFuncs_H #define _MathFuncs_H //定义函数导出 #ifdef __cplusplus #define MyDll extern "C" __declspec(dllexport)   #else #define  My

动态链接库DLL的加载:隐式加载(载入时加载)和显式加载(运行时加载)

静态链接库在链接时,编译器会将 .obj 文件和 .LIB 文件组织成一个 .exe 文件,程序运行时,将全部数据加载到内存. 如果程序体积较大,功能较为复杂,那么加载到内存中的时间就会比较长,最直接的一个例子就是双击打开一个软件,要很久才能看到界面.这是静态链接库的一个弊端. 动态链接库有两种加载方式:隐式加载和显示加载. 隐式加载又叫载入时加载,指在主程序载入内存时搜索DLL,并将DLL载入内存.隐式加载也会有静态链接库的问题,如果程序稍大,加载时间就会过长,用户不能接受. 显式加载又叫运行

Android学习第二天:Toast(提醒)、Menu(菜单)、Intent的显式和隐式(包括打开、适配网站,调用拨号界面等)

1.Toast提醒 为昨天写的按钮程序添加一个提醒,在MainActivity中添加如下代码: Button bt1 = (Button) findViewById(R.id.button_1); bt1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(MainActivity.this, "您点击了按钮1", Toast.

Javascript模块化编程(一)模块的写法最佳实践六、输入全局变量 独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互。 为了在模块内部调用全局变量,必须显式地将其他变量输入模块。

Javascript模块化编程,已经成为一个迫切的需求.理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块但是,Javascript不是一种模块化编程语言,它不支持类class,更遑论模块module了 随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂.网页越来越像桌面程序,需要一个团队分工协作.进度管理.单元测试等等......开发者不得不使用软件工程的方法,管理网页的业务逻辑. Javascript模块化编程,已

go语音之进阶篇显式调用panic函数

1.显式调用panic函数 示例: package main import "fmt" func testa() { fmt.Println("aaaaaaaaaaaaaaaaa") } func testb() { //fmt.Println("bbbbbbbbbbbbbbbbbbbb") //显式调用panic函数,导致程序中断 panic("this is a panic test") } func testc() {

继承和动态内存分配——需要为继承类定义 显式析构函数、复制构造函数和赋值运算符

当派生类使用了new时,必须为派生了定义显式析构函数.复制构造函数和赋值运算符.(这里假设hasDMA类继承自baseDMA类)显式析构函数: baseDMA::~baseDMA() // takes care of baseDMA stuff { delete [] label; } hasDMA::~hasDMA() { delete [] style; } 复制构造函数: baseDMA::baseDMA(const baseDMA & rs) { label = new char[std

AOP系列(一)——ProxyFactoryObject 显式创建AOP代理

AOP概念 Aspect Oriented Programming,面向切面编程,可以通过预编译方式和运行期动态代理,实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. 前提 了解Spring.NET IOC 熟悉代理模式 下面我们结合一个具体的例子来了解AOP. 基本情景 User类 /// <summary> /// 用户实体,具有姓名和年龄两个属性 /// </summary> public class User { public string Name { get