VB 字符串在 OLE 文档中称为 BSTR,并且几乎与 LPWSTR 兼容。它们是每个字符 2 个字节的 Unicode (UTF-16) 字符串,但在字符串指针指向的内存之前的长度为 32 位。
您的代码使用 LPSTR*,它是一个指向每个字符 1 个字节的 ANSI 字符串的指针。显然,您这样做是为了将您的字符串返回到 VB6 代码。
不幸的是,这两者是不相容的。
代码崩溃的原因是您将 VB6 变量 <mystr> 传递给您的函数,但默认情况下它设置为 vbNullString,类似于:
BSTR mystr = NULL;
但是你的主要问题是VB不可能使用你写的C函数。无法为 LPSTR* 编写 Declare 语句。如果您将 C 代码更改为
include “windows.h”
Int __stdcall WritestStr(LPSTR mystr)
{
const LPSTR myconststr = “Venancio Guedes”;
if (mystr)
int destlen = strlen(mystr);
int srclen = strlen(myconststr);
if (destlen >= srclen)
{
strcpy(mystr, myconststr);
return 0;
}
return srclen;
}
...您可以将声明更改为:
Private Declare Function WritestStr Lib “teststr.dll” (ByVal mystr As String) As Long
...并确保您声明一个缓冲区以接受该字符串。您可以为 LPSTR 编写 Declare 语句,但您需要
Private Sub command1_Click()
Dim mystr As string
Dim nLen As Long
mystr = Space$(1024)
nLen = WritestStr(mystr)
Msgbox Left$(mystr, nLen)
End Sub
这让人想起大多数 Win32 API 函数的工作方式。
将 mystr 作为 ByVal 传递通知 VB6 它必须将 <mystr> 从 BSTR 复制到临时 LPSTR,并将指针传递给该缓冲区。当它执行完 WriteStr() 后,它会将 LPSTR 缓冲区复制回原来的 BSTR。
分配一个 VB 字符串缓冲区 <mystr> 以传递给您的函数可以让您回写一些东西。
或者,您可以重写您的 C 程序以本机接受 BSTR(如果您想拥有多语言,这是最干净和更便携的解决方案)。在这种情况下,您的原始 VB6 声明将保留,即 ByRef mystr As String。不幸的是,您仍然必须像在这里所做的那样写入缓冲区。
如果你想拥有 LPWSTR*、LPSTR* 或 BSTR*,你必须在类型库中声明你的函数——我没有时间在这里讨论。