PB12.5 借 Visual Studio 2022 开发 dll 调用 vc++ 开发的 dll

xufxuf 2024-02-23 18:22:47

    VC编译的DLL有多种调用方式:__stdcall,__cdecl,__fastcall等,但是PB 可以调用的dll在C++里必须是__stdcall。而且,PB比较方便实用的传参类型也就string 对 char* ,long 对 int ,C++里不少类型PB没法传(我不会,呃)。
    网上C++的各种资源很多,大多数编译好的DLL不是__stdcall的,于是PB就是调用不了。因此借用VC++,做一个DLL调用其它C++的资源,然后开放出PB可以调用的__stdcall的函数接口,成为PBer的无奈选择。最近有个事情恰好需要调用别家提供的DLL,于是尝试使用微软的Visual Studio 2022做了一遍,现在把过程写一下,方便后来人。

 系统配置:

windows10 家庭版 64位
PB12.5 (32位)

一、从Microsoft Store安装Visual Studio Community 2022 ,社区版,免费的。安装之。

安装下载时间不短,要等一会。
二、 在vs2022【开始使用】处,点【创建新项目】

 

 滚动条拉到最下面,【具有导出项的(DLL)动态链接库】,下一步

 这里举例,创建项目名为:aaa

 三、把需要调用的DLL相关的资源加入

    在右边的 解决方案aaa下,右键点击【头文件】标签,再点击【添加】,【现有项】,选择需要调用DLL的头文件(*.h),加入头文件的列表。

    我这个头文件里,有这个函数需要给PB调用:

EXTERN_API LONG WINAPI  Ecode2pic_PB(
	const void* const pCodeData,
	int nDataLen,
	const TCHAR* pszImageFile
	);


四、编写给PB调用的API函数
    在右边的解决方案aaa下,【源文件】下点击【aaa.cpp】,去掉系统默认给出的示例,#include的留着。

然后,加入自己的代码,开发函数去调用需要调用的资源。
这里C语言里的int类型,对应PB里面的long型。char* 对应 ref string 。
 

extern "C"
{
	_declspec(dllexport) int add(int a ,int b)  //这是一个做加法的测试函数,无用,可删
	{
		int c;
		c = a + b;
		return c;
	}

	_declspec(dllexport) int Ecode2pic_PB(char* codedata, char* picfilename) //这是传入数据codedata生成一个二维码图片picfilename的函数
	{
		long len;
		len = strlen(codedata) ;  //获取传入数据的长度
		int ret = 0;
		ret = Ecode2pic((const void*)codedata, len, picfilename); //调用在另一个DLL里无法被PB直接调用的函数
	
		return ret;
	}

}

   我这里简化了函数的参数,原来需要传入codedata字符串长度,我给PB的函数里省略了,不用传长度,直接获取长度不就行了?

   另外,从PB传入的是char*,传给另一个DLL里的函数要求是 const void* const  ,这个不知道怎么转换,于是请【文心一言】帮了一把,文心一言给出了函数调用代码 : Ecode2pic((const void*)codedata, len, picfilename) ,经过测试好用!现在的AI大模型果然牛啊!

五、添加模块定义文件(*.def)

在右边的 解决方案aaa下,右键点击【源文件】,【添加】【新建项】,【Visual C++】【代码】【模块定义文件】

LIBRARY "ecode.dll"
EXPORTS
add
Ecode2pic_PB

六、一些关键配置项

在右边的 解决方案aaa下,aaa(项目)右键点击,最下面点【属性】。

PB是32位的,所以配置都要设置给win32用。模块定义文件,要选中上面新生成的def文件。

要设置本DLL给的API是用__stdcall方式调用的 

    要传递字符串,所以要与PB使用的字符集匹配。原来默认是unicode的,但是,我们DLL可能要给PB9及以前版本用的话,还是ANSI的更好吧,所以,我这里选了未设置,就是ANSI的。但是这样PB10以后版本的,在函数定义里要有 Alias for 子句。

 

七、编译

    菜单下的一排工具栏里,要选 【Release】【X86】。PB是32位的,用X86的就是32位的。

 

然后,菜单里【生成】,【Build aaa】。

八、拷贝DLL

    把编译出来的DLL和调用函数所在的DLL及依赖的DLL都要复制到PB代码所在文件夹里。

九、PB里面申明及调用
这个是PB里面的函数申明:

function long add(long a,long b) library "aaa.dll" Alias for "add;ANSI"
function long Ecode2pic_PB(ref string codedata, ref string picfilename) library "aaa.dll" Alias for "Ecode2pic_PB;ANSI"

下面是PB里面的函数调用 :

long c
int a=2
int b=3
c=add(a,b)
messagebox('',string(c))


long ret
string ls_pathfilename
string ls_data
ls_data=sle_data.text
ls_pathfilename=sle_pathfilename.text
ret=Ecode2pic_PB(ref ls_data,ref ls_pathfilename)
messagebox('ret',string(ret))

十、总结

    现在大模型帮助下,能解决不少问题,难得一用的东西,也能拾起来试试了。

...全文
264 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

1,083

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 相关问题讨论
社区管理员
  • 基础类社区
  • WorldMobile
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧