如何在Visual Basic DLL和C ++ DLL之间创建隔离/无注册COM? [英] How to create isolated/reg-free COM between Visual Basic DLLs and a C++ DLL?

查看:127
本文介绍了如何在Visual Basic DLL和C ++ DLL之间创建隔离/无注册COM?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在C ++ DLL中使用VB(COM)DLL。
我想出了如何从C ++ DLL访问VB(COM)DLL和它的工作原理。

I have to use a VB (COM) DLL in a C++ DLL. I figured out how to access the VB (COM) DLL from the C++ DLL and it works.

现在我有问题,使用孤立的COM / reg-free COM,因为我不能在每个PC上注册DLL它必须使用。

Now I've got the problem that I have to use isolated COM/reg-free COM because I can't register the DLL on every PC it has to be used on.

我想要使用清单文件实现这个,但我不能得到它的工作,我不知道是什么错误。

I figured out to use manifest-files to achieve this but I can't get it to work and I don't know what is wrong.

我有一个VB DLL名为AccConnVB.dll与以下AccConnVB。清单文件:

I have a VB DLL called AccConnVB.dll with the following AccConnVB.manifest file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
 manifestVersion="1.0">
<assemblyIdentity
        type="win32"
        name="AccConnVB"
        version="1.0.0.0" />
<clrClass
        clsid="{70da7ef0-1549-4b27-9b00-ade5f37aecbe}"
        progid="AccConnVB.AccConnVB"
        threadingModel="Both"
        name="AccConnVB.tables" >
</clrClass>
</assembly>

和一个名为AccConn.dll的C ++ DLL,其中包含以下AccConn.manifest文件:

And a C++ DLL called AccConn.dll with the following AccConn.manifest file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
  manifestVersion="1.0">
<assemblyIdentity
        type = "win32"
        name = "AccConn"
        version = "1.0.0.0" />
<dependency>
        <dependentAssembly>
                    <assemblyIdentity
                                type="win32"
                                name="AccConnVB"
                                version="1.0.0.0" />
        </dependentAssembly>
</dependency>
</assembly>

我的C ++ DLL #define s <$在其stdafx.h和 #import 中的AccConnVB.tlb中使用 no_namespace 的c $ c> _WIN32_DCOM $ c>。

My C++ DLL #defines _WIN32_DCOM in its stdafx.h and #imports the AccConnVB.tlb with no_namespace.

以下是来自C ++ DLL的方法:

The following is a method from the C++ DLL:

JNIEXPORT jint JNICALL Java_natives_AccessConnection_refreshImportZwei
(JNIEnv *env, jclass jobj, jstring jDatabase){
  jint result;
  CComBSTR database;

  const char* nativeDatabase = env->GetStringUTFChars(jDatabase,0);
  database.Append((LPCSTR) nativeDatabase);

  CoInitializeEx(NULL,COINIT_MULTITHREADED);
  {
      ITablesPtr ptr;
      HRESULT hr = ptr.CreateInstance(__uuidof(tables));
      if (SUCCEEDED(hr))
      {
          result = (jint) ptr->refreshImportZwei(BSTR(database));
      }
  }
  CoUninitialize();
}


$ b $ p我确保一切都与注册的AccConnVB.dll配合使用,

I made sure that everything works with a registered AccConnVB.dll, but using it on a computer where it is not registered fails.

清单文件是通过在cmd.exe中执行mt.exe来嵌入的,并带有以下行: mt -manifest H:\AccConnVB.manifest -outputresource:H:\AccConnVB.dll;#1 ,分别用于AccConn.dll和AccConn.manifest。

The manifest files are embedded through executing mt.exe in cmd.exe with the following line: mt -manifest H:\AccConnVB.manifest -outputresource:H:\AccConnVB.dll;#1, for AccConn.dll and AccConn.manifest respectively.

没有其他设置,当访问AccConn.dll时,AccConnVB.dll,AccConn.manifest和AccConnVB.manifest在同一个文件夹中。

Nothing else is set, when accessing AccConn.dll the AccConnVB.dll, the AccConn.manifest and the AccConnVB.manifest are in the same folder.

我按照这里的演练,尝试了一些变化,但没有什么工作

I followed the walkthrough here and tried some variations of it but nothing worked.

非常感谢大家!

附件1

AccConn.manifest:

AccConn.manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
  manifestVersion="1.0">
<assemblyIdentity
     type = "win32"
    name = "AccConn"
    version = "1.0.0.0" />
<file name="AccConnVB.dll">
<comClass
        clsid="{70da7ef0-1549-4b27-9b00-ade5f37aecbe}" 
    tlbid="{1CA12FB4-4A5C-41FF-A508-DCC6CE0D26CD}"
    progid="AccConnVB.tables" />
<typelib
    tlbid="{1CA12FB4-4A5C-41FF-A508-DCC6CE0D26CD}"
    version="1.0" helpdir="" />
</file>
<dependency>
    <dependentAssembly>
                <assemblyIdentity
                            type="win32"
                            name="AccConnVB"
                            version="1.0.0.0" />
    </dependentAssembly>
</dependency>
</assembly>

AccConnVB.manifest:

AccConnVB.manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
 manifestVersion="1.0">
<assemblyIdentity
    type="win32"
    name="AccConnVB"
    version="1.0.0.0" />
</assembly>

附件2

OfficeConn.manifest - C ++ - DLL - (更改名称):

OfficeConn.manifest - C++-DLL - (changed the name):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="OfficeConn.dll" hashalg="SHA1">
    <comClass clsid="{2C0D73B5-7AA4-4D17-970D-042804E206B2}" tlbid="{DB27F83B-DD8E-4AD8-A6A3-9232A9C1692C}">
    </comClass>
    <typelib tlbid="{DB27F83B-DD8E-4AD8-A6A3-9232A9C1692C}" version="1.0" helpdir="" flags="HASDISKIMAGE">
    </typelib>
</file>
<comInterfaceExternalProxyStub name="IOffice" iid="{19485BDA-0BAE-3527-8F9B-C90B43746B03}" tlbid="{DB27F83B-DD8E-4AD8-A6A3-9232A9C1692C}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}">
</comInterfaceExternalProxyStub>
<comInterfaceExternalProxyStub name="_offClass" iid="{1FA5D7FC-1CAE-49E0-A99E-B97E8FE3466E}" tlbid="{DB27F83B-DD8E-4AD8-A6A3-9232A9C1692C}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}">
</comInterfaceExternalProxyStub>
</assembly>

OfficeConnVB.manifest - VB-DLL-(更改名称):

OfficeConnVB.manifest - VB-DLL - (changed the name):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="OfficeConnVB" version="1.0.0.0" publicKeyToken="38d072ba2818144d" processorArchitecture="msil">
</assemblyIdentity>
<clrClass clsid="{2c0d73b5-7aa4-4d17-970d-042804e206b2}" progid="OfficeConnVB.offClass" threadingModel="Both" name="OfficeConnVB.offClass" runtimeVersion="">
</clrClass>
<clrSurrogate clsid="{453B8C28-201B-3705-8CF1-C492C7B259EA}" name="Microsoft.Office.Interop.Outlook.OlDefaultFolders">
</clrSurrogate>
<clrSurrogate clsid="{B5181856-6837-3E65-AF7B-5020DD408339}" name="Microsoft.Office.Interop.Outlook.OlItemType">
</clrSurrogate>
<clrSurrogate clsid="{ECE70AEA-B928-3392-AE59-01373B29D3DA}" name="Microsoft.Office.Interop.Outlook.OlImportance">
</clrSurrogate>
<clrSurrogate clsid="{D74B5B88-8D75-3D21-A9BA-F6DBDC905F75}" name="Microsoft.Office.Interop.Word.WdSaveOptions">
</clrSurrogate>
<file name="OfficeConnVB.dll" hashalg="SHA1">
</file>
</assembly>


推荐答案

你犯了一个奇怪的常见错误,解决鸡鸡蛋问题。有关清单工作方式的简短说明可能有帮助。

You are making an oddly common mistake, expecting Windows to solve the chicken-and-egg problem. A brief word about the way manifest works might help.

Windows在加载可执行文件时加载清单的内容,这些条目将添加到内部查找表中。每当应用程序首先请求创建COM对象时,底层调用是提供CLSID guid的CoCreateInstance(),它首先查询该查找表。如果CLSID是匹配,则条目告诉它必须加载什么DLL。如果没有匹配,那么它会回到传统的注册表查找。

Windows loads the content of a manifest when it load an executable file, the entries are added to an internal lookup table. Whenever an application first asks to create a COM object, underlying call is CoCreateInstance() which supplies the CLSID guid, it first consults that lookup table. If the CLSID is a match then the entry tells it what DLL must be loaded. If there is no match then it falls back to the traditional registry lookup.

鸡和鸡蛋是你的DLL没有加载。因此其清单条目尚未激活。

The chicken-and-egg is that your DLL didn't get loaded yet. So its manifest entries are not yet active.

蛋必须先到,< clrClass> 条目需要进入你嵌入在C ++可执行文件的清单。像这样:

The egg must come first, the <clrClass> entry needs to go into the manifest you embed in the C++ executable. Like this:

  <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity type="win32" name="AccConn" version="1.0.0.0" />
    <file name="foobar.dll"/>
    <clrClass ...etc>
    </clrClass>
  </assembly>

MSDN文章在这里

这篇关于如何在Visual Basic DLL和C ++ DLL之间创建隔离/无注册COM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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