如何在不通过 COM 的情况下从 VB6 调用 C++ DLL? [英] How to call a C++ DLL from VB6 without going through COM?

查看:30
本文介绍了如何在不通过 COM 的情况下从 VB6 调用 C++ DLL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

有这样的对象:

字符串^数组^

我不完全确定它们是什么.我对 C++ 的了解不是很广泛,而且我只用 C++ 为 Linux 系统编写过代码,尽管从使用上看,它们有点像指针.这些对象与 C++ 中的 DLL 有什么关系吗?

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

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

记住,我需要从 VB6 访问这个 C++ DLL 中的所有函数和对象.

谢谢.

向问题添加了 .h 文件和 AssemblyInfo.cpp 规范

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

//myDBObject.h#pragma once使用命名空间系统;命名空间 myDBNamespace {#include "问题解决方案.h"公共引用类 MyDataBaseAccessor{民众:MyDataBaseAccessor();静态字符串 ^ GetServiceVersion() { 返回 sDLLVersion;};int GetServiceStatus() { return myiDBStatus;};字符串 ^ GetMyVersion();字符串 ^ GetDBVersion();字符串 ^ GetDLLVersion();字符串 ^ GetExpireDate();MyOtherObject ^ GetMyOtherObject();int ProcessProblem(ProblemSolution ^ dsps);私人的:静态 MyDataBaseController ^ myDataBase;静态 MyOtherObject ^ myObjs;静态 MyDataset ^ myDS;静态字符串 ^ myDBPath;静态字符串 ^ sDLLVersion = "0.01";静态字符串 ^ sReqDBVer = "0.01";静态 int myiDBStatus;static bool myBoolean, myOtherBoolean, mybNoChain;};}

这是 AssemblyInfo.cpp 文件:

#include "stdafx.h"使用命名空间系统;使用命名空间 System::Reflection;使用命名空间 System::Runtime::CompilerServices;使用命名空间 System::Runtime::InteropServices;使用命名空间 System::Security::Permissions;////关于程序集的一般信息是通过以下方式控制的//属性集.更改这些属性值以修改信息//与程序集相关联.//[assembly:AssemblyTitleAttribute("我的产品标题")];[程序集:AssemblyDescriptionAttribute("")];[装配:AssemblyConfigurationAttribute("")];[assembly:AssemblyCompanyAttribute("我的公司")];[assembly:AssemblyProductAttribute("我的产品名称")];[程序集:AssemblyCopyrightAttribute("我的版权")];[程序集:AssemblyTrademarkAttribute("我的程序")];[装配:AssemblyCultureAttribute("")];////程序集的版本信息由以下四个值组成:////主要版本//次要版本//内部编号//     修订////您可以指定所有值,也可以默认版本号和内部版本号//通过使用*",如下所示:[程序集:AssemblyVersionAttribute("1.0.*")];[程序集:ComVisible(真)];//这里是ComVisible标签.这是假的,我把它设置为真[程序集:CLSCompliantAttribute(true)];[程序集:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = false)];

解决方案

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

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

<块引用>

以最简单的形式,您可以:

REGASM MyAssembly.dll

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

Dim net As ObjectSet obj = CreateObject("NETProject.Foo")对象移动

<块引用>

很简单.除了你迟到绑定,因为你没有 COM类型库.

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

REGASM MyAssembly.dll/tlb:MyAssembly.tlb

现在,在 VB6 中,您可以添加对类型库并尽早使用绑定:

Dim net As Foo设置 obj = New NETProject.Foo对象移动

像这样使类 COM 可见:

[ComVisible(true)]公共引用类 MyDataBaseAccessor

OK, so I have a C++ project that compiles to a DLL file. I am able to reference this file in C# and see/use all of the objects and functions within the DLL file. What I need to do is to reference those objects and function through VB6.

The C++ code has nothing in it that looks like it's creating a DLL. There are no '__declspec(dllexport)' modifiers, just C++ code.

There are objects like this:

String ^
Array^

I'm not entirely sure what they are. My knowledge of C++ is not very extensive and I've only coded in C++ for Linux systems, although from the usage they sort of look like pointers. Do these objects have anything to do with a DLL in C++?

Anyway, I can add any wrappers that I need or add a definition file (.def), although I do not know what wrappers to use and I don't know how a definition file works or how it needs to be constructed.

Any help and/or suggestions are appreciated. If you can refer me to some good info as well, that would be helpful. All searching I have done has not helped.

Remember, I need to access all functions and objects in this C++ DLL from VB6.

Thanks.

EDIT: Added .h file and AssemblyInfo.cpp spec to the question

I changed some names in these files, but the structure is the same. Note that this references other files, but I assume that if one can be made to work then the others can with the same process. I can see every object, just not the methods:

//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;

};
}

Here is the AssemblyInfo.cpp file:

#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)];

解决方案

Use regasm to create a COM Type Library (.TLB) file from your C++/CLI assembly.

You should now be able to reference the C++/CLI code by referencing the TLB file in your VB6 code. From the example there:

In its simplest form, you can do:

REGASM MyAssembly.dll

Now, all of the COM-compatible classes are registered as COM objects. You can fire up VB6 and start writing code:

Dim net As Object

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

Pretty easy. Except that you're late binding because you don't have a COM type library.

No problem! REGASM can generate a type library for you and even register it:

REGASM MyAssembly.dll /tlb:MyAssembly.tlb

Now, in VB6 you can add a reference to the type library and use early binding:

Dim net As Foo

Set obj = New NETProject.Foo
obj.Move

EDIT: Make the class COM visible like this:

[ComVisible(true)]
public ref class MyDataBaseAccessor

这篇关于如何在不通过 COM 的情况下从 VB6 调用 C++ DLL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆