什么vb6类型与std :: vector兼容ABI?

Ill*_*ess 2 c++ vb6 dll stdvector

我一直在用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;
};
Run Code Online (Sandbox Code Playgroud)

我还在VB6中定义了"Object struct"

Private Type Object
    CoordX As Integer 
    CoordY As Integer 
    Width As Integer
    Height As Integer
    Id As String 
End Type
Run Code Online (Sandbox Code Playgroud)

问题是我不知道什么vb6类型可以代表std :: vector以调用DLL的函数.

注意:
- 我使用DLL的向量来添加对象.
- 我使用指针以尽可能少地使用内存.
- 对不起我的英语,这根本不是我的母语.
- 感谢您阅读并试图帮助我.

编辑:
- 我修复了输入问题(Ids肯定是由NullChar结束的,所以LPSTR应该这样做). - 我读了你的答案,我要感谢你们两位,你们的答案彼此接近,一个重大问题依然存在.我的DLL肯定需要向容器添加元素.因此,我想知道如何才能做到这一点.也许我可以为我的函数添加一个返回类型,然后使该函数能够返回它创建的项目(而不是直接将它放入容器中),以便vb6应用程序获取这些项目并能够处理它们,但是我无法弄清楚如何做到这一点

编辑之二:

@Rook:我觉得我可以通过使用一个新的结构来实现这一点.
struct ObjectArrayPointer
{
Object*Pointer;
size_t柜台;
}

然后以这种方式调用我的函数:

void __stdcall DLLFunction (ObjectArrayPointer*);
Run Code Online (Sandbox Code Playgroud)

然后我就可以添加对象并编辑我的VB6应用程序的size参数来查找这些新对象.那是你的意思吗?

Roo*_*ook 5

您不应该尝试从DLL导出模板容器.当面对更新的编译器和库时,它们可能会中断(例如,使用C++ 03构建的库不能很好地使用C++ 11构建的代码).

最难以接受的事情是接受指向缓冲区和长度参数的指针,

void __stdcall DLLFunction (Object* buffer, size_t nObjects);
Run Code Online (Sandbox Code Playgroud)

如果容器的大小在执行期间不会改变.这个界面非常简单,任何理解C调用约定的语言都可以轻松访问(例如几乎每一个.)

你已经抛弃了大部分使用a,std::vector因为你已经把它专门化了Object; 你可以考虑一路走来创建你自己的ObjectCollection类,它使用std::vector内部但是提供了一个非模板化的接口.这是一个简单的例子:

// 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
Run Code Online (Sandbox Code Playgroud)

标头中不以任何形式公开模板类型.这很好.

// 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
Run Code Online (Sandbox Code Playgroud)

所有模板代码都被隐藏起来,让你有一个相当干净和简单的界面,它呈现一个不透明的指针类型,可以被外部代码传递,但只能由你自己查询和修改,等等.

编辑:顺便说一句,我已经Object*在上面的代码中使用过.使用普通旧的Object并且避免与客户端代码的内存管理和指针操作相关的所有问题可能更安全和实现.如果Object足够小而且简单,那么通过值可能是更好的方法.

(注意:未检查可兼容性或功能性.E&OE.警告实施者!)