回 帖 发 新 帖 刷新版面

主题:请教:C做Dll出现 Dll调用约定错误

我对C一窍不通,因有急用临时用Dev-C++写了个Dll给VB用,却出错了

__declspec(dllexport) int Test1(int r){
    return (r+1);
}
int __declspec(dllexport)  Test2(){
    return (2);
}




vb中

Declare Function Test1 Lib "dllmain.dll" Alias "_Z5Test1i" (ByVal b As Integer) As Integer
Declare Function Test2 Lib "dllmain.dll" Alias "_Z5Test2v" () As Integer

1.为什么Test2正常返回2而Test1(1)则出现“实时错误49 Dll调用约定错误”?
[em18]

2.请教:怎样用C实现下面的vb语句并让VB调用(比如API)?
Function abc(d() As Byte, e As Integer, f As Byte) as long
d(e) = f
End Function

比如这样调用
Private Sub Form_Load()
Dim a(2) As Byte, b as long
b = abc(a, 1, 2)
b = abc(a, 2, 3)

Caption = str(a(1)) & str(a(2))
End Sub

回复列表 (共8个回复)

沙发

Declare Function Test1 Lib "dllmain.dll" Alias "_Z5Test1i" (ByVal b As long) As long
Declare Function Test2 Lib "dllmain.dll" Alias "_Z5Test2v" () As long

板凳

__declspec(dllexport) int abc(BYTE* d,int e,BYTE f)
{
    d[e]=f;
    return 0;
}

VB和C配合,在VB里最好使用long而不是integer,因为C里的int是32位的,相当于VB里的long

3 楼

VC里面默认的调用约定不是__stdcall,而是__cdecl,两者都是从右向左压栈,但前者是被调用者清栈,后者是调用者清栈。
所以你调用无参数函数时不会出错,带参数函数时出错。
所有的Windows API都是__stdcall协议的(除了一个特殊的wsprintf),而VB调用API也仅支持__stdcall协议。
另外,C里面的int是32位的,对应VB的Long.

__declspec(dllexport) int [color=FF0000]WINAPI[/color] Test1(int r);




基于性能的考虑,我建议所有32位程序别用16位整数类型Integer,而用32位的本机数据类型Long.
另外,你那个函数没有返回值,建议写成下面这个形式:
void WINAPI abc(PBYTE d, int e, BYTE f)
{
    d[e] = f;
}

4 楼

谢谢

__declspec(dllexport) void WINAPI abc(PBYTE d, int e, BYTE f)
{
    d[e] = f;
}



   ordinal hint RVA      name

         2    0 000011D0 _Z3abcPhih
         1    1 000011D0 _Z3abcPhih@12

不过,怎么这里显示两个?该调用哪个呢?

5 楼

你原来那个没删掉吧?C++是允许重载的,函数名相同,调用协议不同,算2个函数的

6 楼

[quote]你原来那个没删掉吧?C++是允许重载的,函数名相同,调用协议不同,算2个函数的[/quote]

调用协议也算是函数的签名?重载是函数名相同,但函数签名不同。

而我记得函数的签名只包括函数名,参数类型,和参数个数。

7 楼

如果要像LZ那样传入e as integer,恐怕DLL里的参数不能用int e,而要用int* e

因为VB默认byref,传过来的是一个地址。

8 楼

是我弄错了,协议和返回值都不算数。

我平时写DLL,一般都是新建一个.def文件,在里面写好输出函数名,这样编译器就不会对函数名做任何修饰,test还是test.

我来回复

您尚未登录,请登录后再回复。点此登录或注册