C\C++ DLL调用(dll函数重载未解决)

1、首先,建立一个项目,注意要勾选 动态链接库(DLL)。

fun.h, 定义需要给外部调用的函数

#pragma once
#include<string>
#include<iostream>

#define FUN_API _declspec(dllexport)

EXTERN_C FUN_API int fun1(int a, int &b, std::string c);

fun.cpp

// fun_dll.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "fun_dll.h"

FUN_API int fun1(int a, int & b, std::string c)
{
	std::cout << "fun1 load succeed!" << std::endl;
	//return FUN_API int();
	a++;
	b++;
	std::cout << "a=\t" << a << std::endl;
	std::cout << "b=\t" << b << std::endl;
	std::cout << "c=\t" << c << std::endl;
	return 1;
}

  编译 准备好dll。

2、新建项目,加载dlll

#include<windows.h>
using namespace std;

static HINSTANCE hDllInst = NULL;

int init(void)
{
	// Way1 use LoadLibraryEx( ) and obsolute dir to laod DLL
	//hDllInst = LoadLibraryEx(_T("D:\\TEST\\x64\\Release\\fun.dll"),NULL,LOAD_WITH_ALTERED_SEARCH_PATH);

	 Way2
	//TCHAR chCurDir[MAX_PATH] = { 0 };
	//GetCurrentDirectory(MAX_PATH, chCurDir);		// save current dir for main-exe
	//SetCurrentDirectory(_T("..\\..\\TEST\\x64\\Release\\"));		//	jump to dir for dll
	//hDllInst = LoadLibrary(_T("fun.dll"));			//load DLL in dir for dll
	//SetCurrentDirectory(chCurDir);				//jump back to current dir

	hDllInst = LoadLibrary(_T("fun.dll"));
	if (hDllInst == NULL)
	{
		printf("loading fun.dll failed: %d\r\n", GetLastError());
		return -1;
	}
	return 0;
}

int point_cloud_calc_deinit(void)
{
	FreeLibrary(hDllInst);
	return 0;
}

3、取出dll中 对应的函数

// Dll_usage.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include<Windows.h>
#include<tchar.h>

static HINSTANCE dll_init = NULL;

int initial_dll() {
	 Way1 use LoadLibraryEx( ) and obsolute dir to laod DLL
	//dll_init = LoadLibraryEx(_T("D:\\fun_dll\\x64\\Release\\PC_calc.dll"),NULL,LOAD_WITH_ALTERED_SEARCH_PATH);

	// Way2
	TCHAR chCurDir[MAX_PATH] = { 0 };
	GetCurrentDirectory(MAX_PATH, chCurDir);		// save current dir for main-exe
	SetCurrentDirectory(_T("..\\..\\fun_dll\\x64\\Release\\"));		//	jump to dir for dll
	dll_init = LoadLibrary(_T("fun_dll.dll"));			//load DLL in dir for dll
	SetCurrentDirectory(chCurDir);				//jump back to current dir

	 Way3
	//dll_init = LoadLibrary(_T("fun_dll.dll"));
	//if (dll_init == NULL){
	//	printf("loading fun_dll.dll failed: %d\r\n", GetLastError());
	//	return -1;
	//}
	return 0;

}

int fun1(int a, int &b, std::string c) {
	typedef int(WINAPI *pDll)(int a, int & b, std::string c);    //根据函数实际的返回值来 
	pDll p_dll = NULL;
	p_dll = (pDll)GetProcAddress(dll_init, "fun1");
	if (p_dll) {
		return p_dll(a, b, c);
	}
	else {
		std::cout << "Loading fun1 failed!" << std::endl;
		return -1;
	}
}

int main()
{
	initial_dll();
	int a = 1, b = 2;
	std::string c = "quelquefois";
	int res = fun1(1, b, c);
	std::cout << "fun1()=" << res << std::endl;
    std::cout << "Hello World!\n"; 
}

即可调用。

结果发现 string并没有传递到dll函数中。

常见问题:

1、跨目录调用 找不到dll

跨目录调用 调用dll LoadLibrary返回126

2、调用dll中的函数,无法传递string类型

 解决方法一:改用char*,因为dll的接口使用的是c的那一套,加入c++的东西(例如string),不兼容。但这也反应了语言的缺陷。要么不能用string,使用后直接报错。

修改dll中函数定义 如下:

//FUN_API int fun1(int a, int & b, std::string c)
FUN_API int fun1(int a, int & b, char* c)
int main()
{
	initial_dll();
	int a = 1, b = 2;
	//std::string c = "quelquefois";
	char c[] = "quelquefois";
	int res = fun1(1, b, c);
	std::cout << "fun1()=" << res << std::endl;
    std::cout << "Hello World!\n"; 
}

这下得到了预期的结果了。

 

进阶:最近想在dll中实现函数重载,查阅了很多资料,没有找到很方便的方法。在普通的c++中函数重载是很容易的事情,折腾了一中午,决定放弃在dll中弄重载。

关于 extern “C”:若使用extern “C”,则函数名称保持不变,调用较方便,但是不支持函数重载等一系列c++功能;若不使用extern “C”,则调用前要查看编译后的符号,非常不方便。

dll更多说明参考:

http://www.cnblogs.com/findumars/p/5636506.html

dll函数重载,这种并不是我想要的,反而更加麻烦了你说是不是==

https://www.xuebuyuan.com/643161.html

对了,有个思路是 封装成类,再导出dll,这样就可以在dll中实现函数重载了,等我有空了再来试试

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Quelquefois

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值