- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我一直在用 C++ 编写 DLL,现在我必须从 VB6 应用程序调用这个 DLL。
这是此 DLL 的代码示例:
#include <vector>
#include <string>
using namespace std;
void __stdcall DLLFunction (vector<Object>*)
{
// performs a few operations on the Objects contained in the vector.
}
struct Object
{
long CoordX;
long CoordY;
long Width;
long Height;
LPSTR Id;
};
我还在 VB6 中定义了“对象结构”
Private Type Object
CoordX As Integer
CoordY As Integer
Width As Integer
Height As Integer
Id As String
End Type
问题是我不知道什么 vb6 类型可以代表 std::vector 以便调用 DLL 的函数。
注意事项:
- 我使用 DLL 的 vector 来添加对象。
- 我使用指针是为了尽可能少地使用内存。
- 对不起我的英语,它根本不是我的母语。
- 感谢您阅读并试图帮助我。
编辑:
- 我修复了打字问题(Id 肯定以 NullChar 结尾,所以 LPSTR 应该可以解决问题)。- 我读了你们的回答,我要感谢你们两个,你们的答案很接近,但一个主要问题仍然存在。我的 DLL 肯定需要向容器中添加元素。因此,我想知道我该怎么做。也许我可以向我的函数添加一个返回类型,然后使该函数能够返回它创建的项目(而不是直接将其放入容器中),以便 vb6 应用程序获取这些项目并能够处理它们,但是我不知道该怎么做
编辑之二:
@Rook:我觉得我可以通过使用新结构来实现这一目标。
结构 ObjectArrayPointer
{
对象*指针;
size_t 计数器;
}
然后这样调用我的函数:
void __stdcall DLLFunction (ObjectArrayPointer*);
然后我就可以为我的 VB6 应用程序添加对象并编辑大小参数以找到这些新对象。你是这个意思吗?
最佳答案
无论如何,您都不应该尝试从 DLL 中导出模板容器。当面对较新的编译器和库时,它们很可能会崩溃(例如,在 C++03 下构建的库不能很好地与使用 C++11 构建的代码配合使用)。
最不痛苦的事情是接受一个指向缓冲区的指针和一个长度参数,
void __stdcall DLLFunction (Object* buffer, size_t nObjects);
如果容器的大小在执行过程中不会改变。这个接口(interface)非常简单,任何理解 C 调用约定的语言(例如,几乎所有语言)都可以轻松访问它。
您已经放弃了 std::vector
的大部分使用,因为您已经将它特化为 Object
;您可以考虑一路走下去并创建自己的 ObjectCollection
类,该类在内部使用 std::vector
但提供非模板化接口(interface)。这是一个简单的例子:
// In your public API header file:
typedef struct object_collection_t *object_collection;
object_collection CreateObjectCollection();
void DestroyObjectCollect(object_collection collection);
void AddObjectToCollection(object_collection collection, Object* object);
// etc
没有模板类型以任何形式暴露在标题中。这很好。
// And the corresponding code file:
struct object_collection_t
{
std::vector<Object*> objects;
};
object_collection CreateObjectCollection() { return new object_collection_t; }
void DestroyObjectCollect(object_collection collection) { delete collection; }
void AddObjectToCollection(object_collection collection, Object* object)
{
collection->objects.push_back(object);
}
// etc
所有的模板代码都被隐藏起来,给你留下一个相当干净和简单的界面,它呈现一个不透明的指针类型,可以被外部代码传递,但只能由你自己查询和修改,等等。
编辑:顺便说一下,我在上面的代码中使用了Object*
。仅使用普通的旧 Object
并避免所有与客户端代码的内存管理和指针操作相关的问题可能更安全、更简单。如果 Object
足够小和简单,按值传递可能是更好的方法。
(注意:未检查可编译性或功能。E&OE。警告实现者!)
关于c++ - 什么 vb6 类型与 std::vector 兼容 ABI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11222087/
我是 Linux 系统编程新手,在阅读时遇到了 API 和 ABILinux系统编程。 API定义: An API defines the interfaces by whichone piece o
ABI 标准中与内存布局相关的规范是否通常仅适用于 ABI 边界,或者也适用于例如在翻译单元中,或者如果不是这种情况,编译器通常会做出这样的额外保证吗? 如果“一般”太宽泛,请考虑例如带有 Syste
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 6 年前。 Improve this qu
当我尝试使用调试配置在 QtCreator 中运行我的项目时,出现以下错误: 我什至不知道 ABI 是什么。我应该检查哪些设置?可能出了什么问题? 这是我的“桌面”配置: 当我将其悬停时,QtCrea
什么是 ABI,为什么 C++ 没有标准的 ABI,如果有它为什么重要? 最佳答案 ABI 是一个 Application Binary Interface .它描述了如何组织和访问应用程序二进制文件
Fatal Error: Mismatch between the program and library build versions detected. The library used 3.0
我上次在 Android Studio 中将 NDK 版本升级到最新版本后遇到了这个问题。我还找到了解决此问题的解决方案。如果有人有这个问题,我希望这是对你最好的问题和答案。请检查我的答案。 最佳答案
是否可以在没有源代码的情况下获取已知合约地址的ABI? 我发现的唯一方法是使用 etherscan 的 API,但它仅适用于经过验证的合约。 最佳答案 简单的回答:不 长答案:也许吧。 ABI 是从源
不解决 C++ 某些问题的常见解释是它会破坏 ABI 并需要重新编译,但另一方面,我遇到了这样的语句: Honestly, this is true for pretty much all C++ n
我想知道 C 头文件和 ABI 之间的关系。各种类型的大小是体系结构甚至依赖于编译器的。那么如何才能可靠地链接到 C 库呢? 对于一个更具体的问题:当使用 Haskell 的 FFI 时,甚至只使用像
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 4年前关闭。 Improve this questi
问题: 在使用 Android Studio 时,我无法在 HTC One M7 或任何模拟器上安装我的应用程序。在升级到 5.0.2(从 4.4?)之前,它运行良好。我收到的错误消息是 INSTAL
前言:这个问题已经过时了。 在创建 Android 虚拟设备 (AVD) 时,可以选择 CPU/ABI。我已经尝试了所有可用的目标——除了 ARM 别无选择。我的目标是 Android 3.2。 我假
标题说明了一切。我将向具有默认值的类的成员函数添加一个参数。该参数属于非平凡类型。这会破坏 ABI 吗?假设我的新库版本将是 M.m.0,它应该可以作为所有使用 M.m-1.x 的链接应用程序的直接替
我有一个配置探测器,它根据平台和版本确定要传递给 g++ 的标志。我通常使用比 native 安装版本更高版本的 gcc,以便访问 C++14 功能。在较旧的平台上,这意味着我需要添加 -D_GLIB
我看到很多关于 C++ 没有标准 ABI 的讨论,就像 C 一样。我很好奇究竟是什么问题。到目前为止,我想出了 名称修改 异常处理 RTTI 还有其他与 C++ 相关的 ABI 问题吗? 最佳答案 在
我正在使用 ethers-rs 编写一个 defi 应用程序。我需要计算 Rust 中的 CREATE2 地址。我在 Rust 中找不到与 abi.encodePacked(token0, token
尝试使用此 setup.py 从空项目创建轮子: 设置.py from setuptools import setup setup(name='bla', version='1') 我调用 pytho
使用 Android Gradle Experimental 插件版本 0.9.1。我需要为每个 ABI 设置不同的静态库搜索路径,有什么方法可以实现吗? 这里是 build.gradle fragm
假设我们有一个接受或返回某种标准类的共享库: //lib.h #include std::vector returnSomeInts(); //lib.cpp #include "lib.cpp"
我是一名优秀的程序员,十分优秀!