作者:猫儿 | 来源:互联网 | 2023-05-19 06:02
c中原型以结构体指针为参数,在VBA中无论是ByvaldasLong还是ByRefdasSTU均会莫名退出,是什么问题引起的?C中函数有问题?求解add.h#ifndefA
c中原型以结构体指针为参数,在VBA中无论是Byval d as Long还是ByRef d as STU均会莫名退出,是什么问题引起的?C中函数有问题?求解
//add.h
#ifndef ADDLL_H_
#define ADDLL_H_
#include
#ifdef ADD_EXPORTS
#define ADDLL_API __declspec(dllexport)
#else
#define ADDLL_API __declspec(dllimport)
#endif //ADD_EXPORTS
#ifdef FORVBA
#define VBAOFCALL __attribute__((__stdcall__))
#else
#define VBAOFCALL __attribute__((__cdecl__))
#endif // FORVBA
#pragma pack(4)
ADD_EXPORTS typedef struct
{
int age;
char fn[12];
}STU;
#ifdef __cplusplus
extern "C" {
#endif
ADDLL_API void VBAOFCALL getString(STU *p);
#ifdef __cplusplus
}
#endif
#endif /*ADDLL_H_*/
//add.c
#include
#include
#define ADD_EXPORTS
#define FORVBA
#include "add.h"
ADDLL_API void VBAOFCALL getString(STU *ptr)
{
const char *stl = "My Test.";
strncpy(ptr->fn, stl,12);
ptr->age = 56;
}
GCC中编译生成 vba.dll 文件
VBA中:
Private Declare Function getString Lib "vba.dll" (Byval n As long) as integer
‘Private Declare Function getString Lib "vba.dll" ( n As STU) as integer 这样也不行
private type STU
age as long
fn(0 to 11) as string
end type
Sub test()
Dim d As STU, i%
Call getString(VarPtr(d))
’Call getString(d)
MsgBox d.age
MsgBox Join(d.fn, "") ’这里总是莫名退出
End Sub
2 个解决方案
没这么用过,一般是用com做中转,所以不知道为何出错
你可以看看这一片文章
不要做A语言代码修改为B语言代码的无用功。
也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。
只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。
即可很方便地让A、B两种语言之间协调工作。
比如:
A将请求数据写到文件a.txt,写完后改名为aa.txt
B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,改名为bb.txt
A发现bb.txt存在时,读取其内容,读完后删除bb.txt
以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。
除非A或B不支持判断文件是否存在、文件读写和文件更名。
但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢?
可以将临时文件放在RamDisk上提高效率减少磨损磁盘。
数据的结构很复杂的话,文本文件的格式问题可参考json或xml
共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出我现在能想到的:
·进程之间松耦合
·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。
·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。
·方便在线开关服务,只需删除或创建该临时文本文件即可。
·方便实现分布式和负载均衡。
·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满)
·……
“跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边,
回头是“使用共享纯文本文件进行信息交流”的岸!