如何在 Visual Basic DLL 和 C++ DLL 之间创建隔离/免注册 COM?

2024-05-11

我必须在 C++ DLL 中使用 VB (COM) DLL。 我弄清楚了如何从 C++ DLL 访问 VB (COM) DLL,并且它可以工作。

现在我遇到了一个问题,我必须使用隔离的 COM/免注册 COM,因为我无法在必须使用它的每台 PC 上注册 DLL。

我想出使用清单文件来实现这一点,但我无法让它工作,而且我不知道出了什么问题。

我有一个名为 AccConnVB.dll 的 VB DLL,其中包含以下 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" />
<clrClass
        clsid="{70da7ef0-1549-4b27-9b00-ade5f37aecbe}"
        progid="AccConnVB.AccConnVB"
        threadingModel="Both"
        name="AccConnVB.tables" >
</clrClass>
</assembly>

以及一个名为 AccConn.dll 的 C++ DLL,其中包含以下 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" />
<dependency>
        <dependentAssembly>
                    <assemblyIdentity
                                type="win32"
                                name="AccConnVB"
                                version="1.0.0.0" />
        </dependentAssembly>
</dependency>
</assembly>

我的 C++ DLL#defines _WIN32_DCOM在其 stdafx.h 和#importcanon.tlb 是no_namespace.

以下是 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();
}

我确保注册的 AccConnVB.dll 一切正常,但在未注册的计算机上使用它会失败。

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

没有其他任何设置,当访问 AccConn.dll 时,AccConnVB.dll、AccConn.manifest 和 AccConnVB.manifest 位于同一文件夹中。

我按照演练进行操作here http://msdn.microsoft.com/en-us/library/ms973915.aspx并尝试了一些变体,但没有任何效果。

提前非常感谢大家!

附件1:

AccConn.清单:

<?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:

<?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 -(更改名称):

<?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 -(更改名称):

<?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>

您正在犯一个奇怪的常见错误,期望 Windows 能够解决先有鸡还是先有蛋的问题。简单介绍一下清单的工作方式可能会有所帮助。

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

先有鸡还是先有蛋的问题是你的 DLL 还没有加载。所以它的清单条目尚未激活。

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

  <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 文章is here https://msdn.microsoft.com/en-us/library/eew13bza%28v=vs.110%29.aspx.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Visual Basic DLL 和 C++ DLL 之间创建隔离/免注册 COM? 的相关文章

随机推荐

  • IE11 元元素破坏 SVG

    我已将 SVG 文件数据直接嵌入到我的 html 中 它在 Chrome 和 Firefox 中显示 但在 IE11 中根本不显示 SVG 的 Pastebin 链接是http pastebin com eZpLXFfD http past
  • Webpack中watch编译时加速scss的方法

    太长了 滚动到底部寻找答案 或者将 Webpack 和 Dart Sass VM 结合起来 https github com sass dart sass releases https github com sass dart sass r
  • 在 .NET Core 中从 HttpResponseMessage 转换为 IActionResult

    我正在将之前在 NET Framework 中编写的一些代码移植到 NET Core 我有这样的事情 HttpResponseMessage result await client SendAync request if result St
  • Spark:出现心跳错误后丢失数据

    我有一个在 Spark 集群上运行的 Python 程序 有四个工作线程 它处理一个包含大约 1500 万条记录的巨大 Oracle 表 检查结果后发现大约有600万条记录没有插入 我的写入功能如下 df write format jdbc
  • 如何在 PyTorch 中对子集使用不同的数据增强

    如何针对不同的情况使用不同的数据增强 转换 Subset在 PyTorch 中吗 例如 train test torch utils data random split dataset 80000 2000 train and test将具
  • 如何在打开导航抽屉时使背景 Activity 变小?

    我想做我的背景Activity打开时稍微小一点Navigation Drawer 模拟存在的效果Airbnb应用 我想最好的解释是截图 但重点不是让 View 变小 而是让它成为与 Drawer 打开 关闭动画同步的动画 因此 如果您开始打
  • 是否可以从 JBoss 容器中部署的所有 .war 文件中读取属性文件

    我已成功将 war 部署到 Jboss Web 容器 其中包含并读取位于 META INF groupid dir artifactid dir 下的 pom properties 为了访问该文件 我在同一 war 中的 JSP 中使用了以
  • 将 try catch finally 块放入另一个 finally 块中

    try catch finally try catch finally 上面的代码好不好 是的 你可以这样做 实际上 在处理想要正确关闭的流时 您甚至需要这样做 InputStream in try catch finally try in
  • QSpinBox 输入 NaN 作为有效值

    我正在尝试扩展 QSpinBox 以能够输入 NaN 或 nan 作为有效值 根据文档 我应该使用 textFromValue valueFromText 和 validate 函数来完成此操作 但我无法让它工作 因为它仍然不允许我输入除数
  • JVM内存段分配

    好吧 我有一个关于 JVM 内存段的问题 我知道每个 JVM 都会选择稍微不同地实现这一点 但这是一个总体概念 在所有 JVM 中应该保持相同 一个在运行时不使用虚拟机执行的标准C C 程序在运行时有四个内存段 代码 堆栈 堆 数据 所有这
  • 从react-loadable中命名webpack块

    我已经成功在我的项目中添加了react loadable库以启用代码分割 我发现的唯一问题是webpack生成的块没有命名 它们被赋予了整数名称 我的反应可加载使用代码是 const AppRootLoadable Loadable loa
  • 使用 React Hook Form 和 Yup 进行文件输入验证

    我尝试使用 React Hook Form 进行文件输入验证 是的 我写了下面的代码 但是当我测试文件的大小时 它在这里显示console log value 0 size 即使我在文件输入中选择了一个文件 该值也是未定义的 这有什么问题吗
  • 如何在Android JUnit测试用例中调用Button.performClick?

    我是 Android 测试方面的新手 我想测试单击按钮是否会打开相应的活动 我做了一些研究 发现我需要使用 ActivityManager 来进行检查 问题是 我无法让 点击 部分正常工作 我正在尝试使用Button performClic
  • 需要用户使用 NTLM 重新进行身份验证

    我是 NTLM web config 中的authenication windows 有一个 asp net mvc 2 0 站点 现在 一旦用户登录 他们就会一次保持登录状态数周 该应用程序的使用正在向共享使用登录服务帐户的计算机的用户开
  • 如何使用 CUDA/Thrust 对两个数组/向量根据其中一个数组中的值进行排序

    这是一个关于编程的概念问题 总而言之 我有两个数组 向量 我需要对一个数组 向量进行排序 并将更改传播到另一个数组 向量中 这样 如果我对 arrayOne 进行排序 则对于排序中的每个交换 arrayTwo 也会发生同样的情况 现在 我知
  • Linux内核页表更新

    在linux x86 中分页 每个进程都有它自己的页面目录 页表遍历从 CR3 指向的页目录开始 每个进程共享内核页目录内容 假设三个句子是正确的 假设某个进程进入内核 模式并更新他的内核页目录内容 地址映射 访问 权利等 问题 由于内核地
  • Python 用静态图像将 mp3 转换为 mp4

    我有x文件包含一个列表mp3我想转换的文件mp3文件至mp4文件带有static png photo 似乎这里唯一的方法是使用ffmpeg但我不知道如何实现它 我编写了脚本来接受输入mp3文件夹和一个 png photo 然后它将创建新文件
  • IllegalStateException:无法更改片段的标签,以前是 android:switcher,现在是 android:switcher

    我的活动使用TabLayout ViewPager 这里的选项卡和页面的数量是动态的 具体取决于从服务器获取的数据 崩溃是通过 Crashlytics 报告的 我无法复制它 我的活动代码 Override protected void on
  • Android Studio 1.0 在 dexDebug 或 dexRelease 上构建失败

    我最近从 Android Studio 0 9 2 升级到 1 0 包括 Gradle 插件版本 1 0 0 并且在构建项目时遇到问题 每当我构建时 我都会在 dexDebug 或 dexRelease 步骤中收到以下异常 UNEXPECT
  • 如何在 Visual Basic DLL 和 C++ DLL 之间创建隔离/免注册 COM?

    我必须在 C DLL 中使用 VB COM DLL 我弄清楚了如何从 C DLL 访问 VB COM DLL 并且它可以工作 现在我遇到了一个问题 我必须使用隔离的 COM 免注册 COM 因为我无法在必须使用它的每台 PC 上注册 DLL