如何在不通过COM的情况下从VB6调用C ++ DLL?

时间:2010-10-01 22:07:21

标签: c++ dll vb6

好的,所以我有一个编译成DLL文件的C ++项目。我能够在C#中引用此文件,并查看/使用DLL文件中的所有对象和函数。我需要做的是通过VB6引用这些对象和函数。

C ++代码中没有任何东西看起来像是在创建DLL。没有'__declspec(dllexport)'修饰符,只有C ++代码。

有这样的对象:

String ^
Array^

我不完全确定它们是什么。我对C ++的了解并不是很广泛,而且我只用C ++编写Linux系统编码,尽管它们的用法看起来像指针。这些对象与C ++中的DLL有关吗?

无论如何,我可以添加我需要的任何包装器或添加一个定义文件(.def),虽然我不知道使用什么包装器,我不知道定义文件是如何工作的或者它是如何构造的

感谢任何帮助和/或建议。如果您也可以向我推荐一些好的信息,那将会很有帮助。我所做的所有搜索都没有帮助。

请记住,我需要从VB6访问此C ++ DLL中的所有函数和对象。

感谢。

编辑:在问题中添加了.h文件和AssemblyInfo.cpp规范

我在这些文件中更改了一些名称,但结构是相同的。请注意,这引用了其他文件,但我认为如果可以使一个文件工作,那么其他文件可以使用相同的过程。我可以看到每个对象,而不是方法:

//myDBObject.h
#pragma once
using namespace System;
namespace myDBNamespace {

#include "ProblemSolution.h"

public ref class MyDataBaseAccessor
{
public:
    MyDataBaseAccessor();

    static  String ^    GetServiceVersion() { return sDLLVersion;};
    int                   GetServiceStatus() { return myiDBStatus;};
    String ^                GetMyVersion();
    String ^                GetDBVersion();
    String ^                GetDLLVersion();
    String ^                GetExpireDate();

    MyOtherObject ^         GetMyOtherObject();

    int             ProcessProblem(ProblemSolution ^ dsps);

private:
    static  MyDataBaseController ^  myDataBase;
    static  MyOtherObject ^         myObjs;
    static  MyDataset ^     myDS;
    static  String ^                myDBPath;

    static  String ^                sDLLVersion = "0.01";
    static  String ^                sReqDBVer = "0.01";
    static  int                     myiDBStatus;
    static  bool                    myBoolean, myOtherBoolean, mybNoChain;

};
}

这是AssemblyInfo.cpp文件:

#include "stdafx.h"

using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;

//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute("My Product Title")];
[assembly:AssemblyDescriptionAttribute("")];
[assembly:AssemblyConfigurationAttribute("")];
[assembly:AssemblyCompanyAttribute("My Company")];
[assembly:AssemblyProductAttribute("My Product Name")];
[assembly:AssemblyCopyrightAttribute("My Copyright")];
[assembly:AssemblyTrademarkAttribute("My Program")];
[assembly:AssemblyCultureAttribute("")];

//
// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:

[assembly:AssemblyVersionAttribute("1.0.*")];

[assembly:ComVisible(true)]; //Here is the ComVisible tag. It was false and I set it to true

[assembly:CLSCompliantAttribute(true)];

[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = false)];

2 个答案:

答案 0 :(得分:2)

  

我不完全确定它们是什么。

您不是在考虑C ++代码,而是在C ++ / CLI代码中,这是一种针对托管.NET平台的语言。这也是您可以在C#中轻松使用此DLL的原因。

老实说,如果你想在Visual Basic 6中使用托管对象,COM Interop是你最好的选择。创建包装器或通过COM Interop直接公开DLL中包含的对象。

修改

基本上,您使用属性公开对象,即使用属性在源代码中注释您的类型。这些记录在此处:System.Runtime.InteropServices

看看: Introduction to COM Interop

此外,COM Interop“圣经”是Adam Nathan撰写的这本书:.NET and COM: The Complete Interoperability Guide

还有一篇文章讨论如何公开COM对象并在VB6中使用它:http://www.15seconds.com/issue/040721.htm

答案 1 :(得分:1)

使用regasm从C ++ / CLI程序集创建COM类型库(.TLB)文件。

现在,您应该可以通过引用VB6代码中的TLB文件来引用C ++ / CLI代码。从那里的例子:

  

最简单的形式是:

     

REGASM MyAssembly.dll

     

现在,所有的   COM兼容的类已注册   作为COM对象。你可以启动VB6   并开始编写代码:

Dim net As Object

Set obj = CreateObject("NETProject.Foo")
obj.Move
  

非常简单。除了你迟到   绑定,因为你没有COM   类型库。

     

没问题! REGASM可以生成一个类型   库给你,甚至注册它:

     

REGASM MyAssembly.dll   /tlb:MyAssembly.tlb

     

现在,在VB6中你可以添加一个引用   类型库并尽早使用   结合:

Dim net As Foo

Set obj = New NETProject.Foo
obj.Move

编辑: 使类COM可见如下:

[ComVisible(true)]
public ref class MyDataBaseAccessor