VB调用VC做的DLL的问题

w080121 2008-03-11 11:19:23
请问,我用VC做了一个DLL,然后用VB调用!但是出现错误对话框,点击确定整个visual basic6.0编辑器都被关掉。请问这是怎么回事?
在VC中的导出函数:extern "C" _declspec(dllexport) analysis(char* inFilePath, char* outFilePath)
在VB中声明和调用:
Private Declare Function analysis Lib "analysis.dll" (inFilePath As String, outFilePath As String)
Private Sub Form_Load()
Call analysis("a.txt", "b.txt")
End Sub
...全文
164 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
seventcheng 2008-10-20
  • 打赏
  • 举报
回复
学习ING!但是在这个C的函数中和VB调用时可不可以用数组.
lyserver 2008-03-14
  • 打赏
  • 举报
回复
楼上的已说得很清楚了,我再强调一点,VB函数调用时的参数是以_stdcall传递的,而不是_cdecl,(入栈顺序和释放方法不一样),且VB的字符串为BSTR类型,如果你真要使用char *,则需要使用VB的Byte数组来传递.
w080121 2008-03-14
  • 打赏
  • 举报
回复
晕死,我把C++里面的导出函数改为:
extern "C" _declspec(dllexport) __stdcall analysis(){}
VB里面这样写:
Private Declare Function analysis Lib "analysis.dll" ()
Private Sub Form_Load()
Call analysis
End Sub
什么事都不做,还是出错,弹出对话框,点击确定后整个vb编辑器都被关掉了!
forbearORfolie 2008-03-14
  • 打赏
  • 举报
回复
给个最简单的例子你

我调式是成功的

vb code:
Private Declare Function analysis Lib "j:\analysis.dll" Alias "_fnAnalysis@8" (ByVal a As Long, ByVal b As Long) As Long

Private Sub Command1_Click()
Dim p As Long, k As Long
Dim ret As Long
p = 100
k = 132342
ret = analysis(p, k)
Print ret
End Sub

vc6,新建win32 dynamic-link library

analysis.cpp code:导出函数
extern "C" ANALYSIS_API _stdcall int fnAnalysis(int a ,int b)
{
int cs;
cs=a+b;
return cs;
}

analysis.h 导出函数原型:
extern "C" ANALYSIS_API _stdcall int fnAnalysis(int a,int b);

w080121 2008-03-14
  • 打赏
  • 举报
回复
多谢各位耐心的回答我这么多低B问题
of123 2008-03-14
  • 打赏
  • 举报
回复
你把全部代码和错误提示贴出来好不好。别让我们猜。

VB 退出肯定是代码致命错误,例如变量未实例化,缓冲区越界写,类型错误造成的访问越界等等。光看声明是看不出来的。

如果你不愿意贴,就自己慢慢搞吧。不必来此絮叨。
w080121 2008-03-14
  • 打赏
  • 举报
回复
找楼上的建议,把function改为sub还是不行啊,一样运行后vb编辑器就出现问题
supergreenbean 2008-03-14
  • 打赏
  • 举报
回复
你声明错了

Private Declare Sub analysis Lib "analysis.dll" ()
lyserver 2008-03-14
  • 打赏
  • 举报
回复
给你一个完整的例子。
一、VC:
1、建一个空的DLL工程,然后新建一个CPP文件,假设为Temp.Cpp,复制以下代码:

// temp1.cpp : Defines the entry point for the DLL application.
//

#include <windows.h>

extern "C" __declspec(dllexport) int __stdcall ShowMessage(char *pszMessage)
{
MessageBox(NULL,pszMessage,"",MB_OK);
return 0;
};

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

2、新建一个文本文件,扩展名必须为def,假设文件名为:Temp.def,复制以下代码:
LIBRARY temp1

EXPORTS ShowMessage

编译成DLL文件,忽略编译过程中的警告。

二、VB:
新建一个空的工程,添加一个模块文件,复制以下代码:
Public Declare Function ShowMessage Lib "F:\表格设计器\temp2\Debug\temp2.dll" (ByVal s As String) As Integer

Sub main()
Dim s As String
Dim b() As Byte
s = "我爱你中国" & Chr(0)
b = StrConv(s, vbFromUnicode)
ShowMessage s
End Sub


ShowMessage将被成功调用。

三、注意事项:
和大多数API不区分大小不同,在VB声明中必须区别大小写,如ShowMessage不同声明为showmessage,否则会失败。
forbearORfolie 2008-03-14
  • 打赏
  • 举报
回复
你新建win32dll之后,自己就有的,汗|,加个extern "C" 和 _stdcall就可以了
w080121 2008-03-14
  • 打赏
  • 举报
回复
请问23楼,ANALYSIS_API 是在哪定义的?也许这个问题很傻,实在不好意思
forbearORfolie 2008-03-13
  • 打赏
  • 举报
回复
重新回复一次

1.vb只支持_stdcall这种C形式的函数导出
2.最好把字串传递,改成strptr取址后的long型传递
3.加上别名 alias "_analysis@8" 让函数更健壮
forbearORfolie 2008-03-13
  • 打赏
  • 举报
回复
csdn好象出了点问题,我回复时,服务器频频出错,这个帖子却出现在‘我回复的帖子’的列表中。
forbearORfolie 2008-03-13
  • 打赏
  • 举报
回复
1.用_stdcall导出
2.把string传递,改成long指针传递,指针值可以用Strptr()取得
3.调用函数时,最好加上别名,alias "_analysis@8"
forbearORfolie 2008-03-13
  • 打赏
  • 举报
回复
1.VB只会调用_stdcall这中C约定的导出函数
2.建议把字串改成用strptr取得的long型字串指针,再传递.
3.增加别名,会让调用函数更准确健壮
Private Declare Sub analysis Lib "analysis.dll" alias "_analysis@8"(ByVal StrPtrinFilePath As long,ByVal StrPtroutFilePath As long)as long
forbearORfolie 2008-03-13
  • 打赏
  • 举报
回复
1,vb只能调用_stdcall这样c方式导出函数
2,用strptr取字符指针传过去

Private Declare Function analysis Lib "analysis.dll" alias "_analysis@8" (Byval PtrinFilePath As long, Byval PtroutFilePath As long)as long
forbearORfolie 2008-03-13
  • 打赏
  • 举报
回复
vb只能调用_stdcall这样的c的调用约定导出的函数
另外,建议不要传递字符串,而改成LONG型的指针,可以用strptr来取

Private Declare Function analysis Lib "analysis.dll" alias "_analysis@8"(Byval strptr(inFilePath) As long, Bybal strptr(outFilePath) As long) as long
加上别名能更准确的调用输出函数
CommandButton 2008-03-12
  • 打赏
  • 举报
回复
另外看得出楼主传送的是char*的文件名,这就必须把路径一个字符一个字符的写到A数组里面,并且一定要在结尾单元写上0,C的字符串结尾符号是0,否则将发生意外。
CommandButton 2008-03-12
  • 打赏
  • 举报
回复
Private Declare Function analysis Lib "analysis.dll" (ByVal inFilePath As long, ByVal outFilePath As long)

DIM A(100) AS BYTE
DIM B(100) AS BYTE

Private Sub Form_Load()
analysis(A(0), B(0))
End Sub
按照以上的思路来改程序,C参数转到VB参数要遵守一个约定,这个约定可以到MSDN里查看。指针就是VB数组的第一个元素的地址。按值传送就可以把地址传到C函数里,传送的是一个32位二进制数,也就C语言中的地址:char* ,其实不管是char*还是long*,或者是int*,都是一个32位地址。在vb里,当然就成了一个long的数值。
这里特别要注意的是DIM A(100) AS BYTE的数组长度100,必须定义固定长度的数组,这个长度也必须比C函数可能处理的长度还要长,否则会出乱子。

楼主用VB字符串来当字节型指针,一来VB字符串是16位一个字符的,而不是8位,二来如果是动态字符串,那格式就更不对了,VB的动态字符串比实际字节还多了10个字节的描述符,拿它当C的char指针传递,根本对不上号
supergreenbean 2008-03-12
  • 打赏
  • 举报
回复
首先,给你C函数前加上__stdcall修饰符
其次,声明写成
Private Declare Sub analysis Lib "analysis.dll" (ByVal inFilePath As String,ByVal outFilePath As String)
加载更多回复(9)

1,453

社区成员

发帖
与我相关
我的任务
社区描述
VB 控件
社区管理员
  • 控件
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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