VB6.0调用VS2022的C++写的DLL,网上很多错的,这里才是最简单的:一定要采用DEF文件。
网上都是VB6.0调用VC6.0的,现在公布下VB6.0调用VS2022的C++写的DLL的方法,用VS2022新建C++动态链接库。

【pch.h】内容如下:
// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。

#ifndef PCH_H
#define PCH_H

// 添加要在此处预编译的标头

#include "framework.h"

#endif //PCH_H
【pch.cpp】内容如下:
// pch.cpp: 与预编译标头对应的源文件

#include "pch.h" // 这里放了你函数的声明

// 当使用预编译的头时,需要使用此源文件,编译才能成功。
#include<iostream>
#include<fstream> // 写文件用于调试用
using namespace std;

long long __stdcall f_AtoI(char str[]) // 字符串转为整数,通过减'0'字符,底层用ASCII码相减
{
	int i = 0;
	long long tempI = 0;

	while (str[i] != '\0')
	{
		tempI = tempI * 10 + (str[i] - '0'); // 于字符0的差距
		++i;
	}

	return tempI; // 转换后赋值给m
}

char* __stdcall f_ItoA(long long n)
{
	static char tmpStr[100]{ 0 };
	static char str[]{ 0 };

	int i(0);
	int j = 0;

	while (n)
	{
		tmpStr[i++] = n % 10 + '0';
		n /= 10;
	}
	// 此时为逆序,需要调整为正序
	while (i > 0)
		str[j++] = tmpStr[--i];
	return str;
}

int __stdcall f_return(int a)
{
	return a;
}

int __stdcall f_add(int a, int b)
{
	return a + b;
}

int __stdcall f_sub(int a, int b)
{
	return a - b;
}

long long __stdcall f_acc(long a, long b)
{
	long long sum = 0;
	// 100000000这个数太大,
	// 求和后超过了int型能表示的范围,
	// 采用long long这一数据类型
	for (long i = a; i <= b; ++i)
		sum += i;

	return sum;
}

char* __stdcall f_acc_str(long a, long b)
{
	long long m = f_acc(a, b);
	char* str3 = f_ItoA(m);

	if (1 == 2)
	{	// 当手工修改成1=1时,就进入调试模式
		// dll调试。由于dll无法写屏幕,那么就写文件,覆盖型dll_show.txt写在当前目录
		std::ofstream ofile("dll_show.txt");
		ofile << str3 << "\n";
		ofile.close();
	}

	//【char* -> char*】借助strcpy_s()拷贝赋值
	char* str4 = new char[strlen(str3) + 1];
	strcpy_s(str4, strlen(str3) + 1, str3); //拷贝str3到str4

	return str4;
}

char* __stdcall f_return_str(char* str)
{

	//char str2[] = "您输入的是:"; //如果要给字符串加东西
	char str2[] = ""; //不写就是空
	char* str3 = str2; //【char[] -> char*】通过"="直接赋值

	//【char* -> char*】借助strcpy_s()拷贝赋值
	char* str4 = new char[strlen(str3) + 1];
	strcpy_s(str4, strlen(str3) + 1, str3); //拷贝str3到str4

	strcat_s(str4, 100, str); //连接str4和str

	return str4;
}
【vcdll.def】内容如下:
LIBRARY dll
EXPORTS

f_return
f_return_str

f_add
f_sub

f_acc
f_acc_str


;分号开头的是注释,上面是要导出的函数,不一定是全部函数,可以选择部分函数导出。没写的函数就先注释掉。
;f_mul
;f_div
关键点来了!点击右边栏目“解决方案vsdll”下的“vsdll”,最下面有“属性”,左侧“配置属性”下“链接器”,子目录“输入”,看到右侧“平台”选“所有平台”,下面“模块定义文件”输入“vcdll.def”这个文件,才有效哦!“确定”,生成DLL的可能在Debug里面,就可以被VB6调用了。 在VB6中声明:
'约定 f_=Function(由于ASP调用vbDLL用字符串方式可能出错,
'所以在这里建议用string得到参数,再转换成数字类型调用vcDLL)

'由于VC6的DLL无需Regsrv32注册,所以可以直接拷贝立即生效
'由于调试程序在组里面,调用的是VB源码,而不是vbDLL,所以不用生成DLL也可以运行。

'如果有重名子函数,可以用Alias改名,在本程序中用f_return_vc指向vcDLL的f_return
'VC6.0写的DLL
Private Declare Function f_return_vc Lib "C:\testvc\vcdll\Release\vcdll.dll" Alias "f_return" (ByVal x As Long) As Long
Private Declare Function f_add_vc Lib "C:\testvc\vcdll\Release\vcdll.dll" Alias "f_add" (ByVal x As Long, ByVal y As Long) As Long
Private Declare Function f_sub_vc Lib "C:\testvc\vcdll\Release\vcdll.dll" Alias "f_sub" _
    (ByVal x As Long, ByVal y As Long, ByVal lpPassword As String, ByVal lngPassword As Long) As Long
Private Declare Function f_acc_vc Lib "C:\testvc\vcdll\Release\vcdll.dll" Alias "f_acc" (ByVal x As Long, ByVal y As Long) As Long

Private Declare Function f_return_vc_str Lib "C:\testvc\vcdll\Release\vcdll.dll" Alias "f_return_str" (ByVal x As String) As String

'VS2022写的DLL
Private Declare Function f_return_vs Lib "C:\testvc\vsdll\Debug\vsdll.dll" Alias "f_return" (ByVal x As Long) As Long
Private Declare Function f_return_vs_str Lib "C:\testvc\vsdll\Debug\vsdll.dll" Alias "f_return_str" (ByVal x As String) As String

Private Declare Function f_add_vs Lib "C:\testvc\vsdll\Debug\vsdll.dll" Alias "f_add" (ByVal x As Long, ByVal y As Long) As Long
Private Declare Function f_sub_vs Lib "C:\testvc\vsdll\Debug\vsdll.dll" Alias "f_sub" (ByVal x As Long, ByVal y As Long) As Long

Private Declare Function f_acc_vs Lib "C:\testvc\vsdll\Debug\vsdll.dll" Alias "f_acc" (ByVal x As Long, ByVal y As Long) As String
Private Declare Function f_acc_vs_str Lib "C:\testvc\vsdll\Debug\vsdll.dll" Alias "f_acc_str" (ByVal x As Long, ByVal y As Long) As String
                                        
'建立自定义函数  64位的IIS中必须开启”应用程序池“->”高级设置“->”常规“->”启用32位应用程序“设置成True
Public Function f_say(strSay As String)
'返回值:VB编写
    f_say = strSay   '可以返回值
End Function

Public Function f_return_vc_use(strX As String)
'返回值:调用vcDLL
    f_return_vc_use = f_return_vc(CLng(Val(strX)))    'Val函数会把不能识别为数字的第一个字符上,停止读入字符串。
End Function

Public Function f_return_vs_use(strX As String)
'返回值:调用vsDLL
    f_return_vs_use = f_return_vs_str(strX)
End Function

Public Function f_sub(x As Long, y As Long)
'对于有保密的子函数,设计了2个参数校验
'因为字符串容易被OD软件反编译看到字符串,所以加入数字;
'而纯数字容易被枚举,所以加入字符串。
    Dim lngPassword As Long
    lpPassword = "ab123cd"
    lngPassword = 56732

    fs_sub = f_sub_vc(x, y, lpPassword, lngPassword)
End Function

Public Function f_acc(strN1 As String, strN2 As String)
'累加:VB编写
'累加 accumulation 由于可以上亿次累加,所以用Double。
    dblN1 = CDbl(strN1)
    dblN2 = CDbl(strN2)

    Dim n As Double
    Dim i As Double

    For i = dblN1 To dblN2
        n = n + i
    Next

    f_acc = n
End Function

Public Function f_acc_vc_use(str1 As String, str2 As String)
'累加:调用vcDLL,上亿次累加VC会出错,得不到最终结果
    f_acc_vc_use = f_acc_vc(CLng(Val(str1)), CLng(Val(str2)))
End Function

Public Function f_acc_vs_use(str1 As String, str2 As String)
'返回值:调用vsDLL
    f_acc_vs_use = f_acc_vs_str(CLng(Val(str1)), CLng(Val(str2)))
End Function
如果要算1到100000000(1亿)的累加,结果是5000000050000000,那么就用 f_acc_vs_str 子函数。DLL可以考虑用本目录地址,或绝对地址。
创作不易,支持我们就点击下方广告用优惠券买东西吧 :)

百事知道 版权所有,禁止转载,除非给出本网网址。