C++ DLL 仅读取安全数组中包含的字符串的第一个字符
C++ DLL only reading first char of a string contained in a safearray
我试图弄清楚如何将用户定义的结构从 VB6 应用程序传递到C++ DLL。
这是我的 VB6 代码示例:
Private Type ObjetVB
Rank As Integer
Id As String
End Type
Private Declare Sub testLObj Lib "D:TestDLL.dll" (Tab_Obj() As ObjetVB)
Private Declare Sub testObj Lib "D:TestDLL.dll" (ByRef Obj As ObjetVB)
Private Sub Command1_Click()
Dim elements(1 To 4) As ObjetVB, i As Long
For i = 1 To 4
elements(i).Rank = i
elements(i).Id = "Pouet"
Next
testLObj elements()
End Sub
Private Sub Command2_Click()
Dim ObjCrash As ObjetVB
ObjCrash.Rank = 1
ObjCrash.Id = "Pouet"
testObj ObjCrash
End Sub
还有我的C++代码示例:
struct ObjetVB
{
short Rank;
char* Id;
};
void videFichier()
{
ofstream fichier("../../../log.txt", ios::out | ios::trunc);
if(fichier)
{
fichier.close();
}
}
int Log(ObjetVB ObjInput)
{
ofstream fichier("../../../log.txt", ios::out | ios::app);
if(fichier)
{
fichier << ObjInput.Rank << endl << "Id : " << ObjInput.Id << endl << endl;
fichier.close();
}
return 0;
}
void __stdcall testObj (ObjetVB* ObjInput)
{
videFichier();
log(*ObjInput);
}
void __stdcall testLObj (SAFEARRAY **Tab_Obj)
{
ObjetVB *elt;
HRESULT ret;
unsigned long i;
videFichier();
if ((ret = SafeArrayAccessData(*Tab_Obj,(void **) &elt))==S_OK)
{
for (i = 0; i < (*Tab_Obj)->rgsabound->cElements; i++)
{
Log(elt[i]);
}
SafeArrayUnaccessData(*Tab_Obj);
}
}
我的问题是,当我单击"Command2"时,我的日志文件如下所示:
1
Id : Pouet
然而,当我单击"Command1"时,它看起来像这样:
1
Id : P
2
Id : P
3
Id : P
4
Id : P
为什么我的C++ DLL 在传递单个项目时将"char* Id"识别为字符链,而当我使用项目数组时,它看起来像是将其识别为指向第一个字符的指针?
而且,最值得注意的是,我该如何解决它?我尝试在我的 c++ 结构中使用 LBSTR 而不是 char*,它没有修复它,我还尝试添加"elements(i)。Id = String (255, vbNullChar)" berfore 初始化 VB6 字符串,但事实证明它也没有帮助。
像往常一样,我要感谢你们所有人花时间阅读并试图提供帮助。
附带说明:英语对我来说是一种外国语言,所以我希望我几乎可以理解,当然,如果不是这样,我深表歉意。
编辑:
我不知道它是否有帮助,但是在尝试了Mark Bertenshaw的建议之后,我也尝试了这个:在 VB6 中:
Id As String * 10
在C++:
char Id[10];
这给出了这个奇怪的结果:
Objet :
32
Id : P
Objet :
1
Id :
Objet :
32
Id : P
Objet :
2
Id :
VB6 返回的是 BSTR 而不是字符数组。 例如,BSTR 将充满宽字符。 对于标准的罗马字母表,我相信 2 字节编码与 ASCII 相同,但第二个字节是 0,因此您的字符串长度似乎为零。
您可以使用 wchar_t* 而不是 char*,您会发现一切似乎都有效。 这不是最好的方法,因为您无法保证wchar_t和 BSTR 的大小相同。
最好的选择是使用 ConvertBSTRToString 函数。
这里发生的事情是 VB 是"有帮助的",并自动将 ID 中的 2 字节 Unicode 字符串 (BSTR) 转换为 1 字节 ANSI 字符串 (char*)。但是,我不完全确定当您将 VB 类型放入数组时它如何处理字符串。
一种可能性是 ObjetVB 结构的打包给您带来了问题。尝试像这样定义它:
Private Type ObjetVB
Id As String ' 4 bytes
Rank As Integer ' 2 bytes
End Type
struct ObjetVB
{
char* Id; // 4 bytes
short Rank; // 2 bytes
}
- 编译包含字符串的代码时遇到问题
- 一个函数,用于查找字符串1包含字符串2 c++的次数
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 为什么我的结构在包含字符串时崩溃?
- C++应在标头和源中包含字符串
- 为什么 cin 在包含字符串标头后接受字符串输入
- 查找字符串是否包含字符串向量的任何一个元素的最佳方法
- 包含字符串的结构的 Boost 进程间向量是否需要特殊的分配器?
- 字符串和输入文件,从包含字符串的 txt 文件中分配多个变量值
- 包含字符串的类:当它从函数返回时会发生什么?
- 从c#lib返回一个包含字符串到c 程序的结构
- c++ 序列化包含字符串和指向另一个对象的指针的对象
- 复制CORBA ::任何包含字符串的corba程序SEG故障
- 为什么即使在启用 C++11 并且我包含字符串之后,'stod'仍然没有在此范围内声明?
- 我正在尝试读取一个包含字符串和整数的二进制文件..并打印出与字符串对应的整数
- 将数组设置为包含字符串值会导致错误
- 如何通过Visual Studio中的预处理器传递包含字符串和引号的环境变量
- 当我在 c++ 中不包含字符串头文件时出错
- 即使包含字符串C++程序的编译错误
- 包含字符串数组的结构的malloc问题