gpt4 book ai didi

c# - 在不注册 DLL 的情况下通过 ComInterop 在 C# 中编码(marshal)非托管 dll

转载 作者:行者123 更新时间:2023-11-30 14:37:55 26 4
gpt4 key购买 nike

我有一个非托管 DLL,我目前正在使用 COM 类包装器从 C# 调用它。

[ComImport(), Guid("75E81043-CAD5-11D3-800D-00105A5E2FA0")]
public class MyObject { }

[ComImport(), Guid("75E81042-CAD5-11D3-800D-00105A5E2FA0"),
InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface MyInterface
{
string EncryptString([In, MarshalAs(UnmanagedType.BStr)] string bstrOrginal);
}

然后调用:

MyInterface obj = (MyInterface)new MyObject();
string crypt = obj.EncryptString("something");

这行得通,返回值如我所料。但是,它要求 dll 已注册到 regsvr32。

我正在寻找一种不需要 regsvr32 的方法来做到这一点。最好只提供 dll 的副本。值得注意的是,我有非托管 dll 的源代码,并且可以根据需要修改它。

将不胜感激朝着正确的方向前进。

最佳答案

我自己也想做同样的事情。正如 Jim 提到的那样,可以获取 DllRegisterServer 的地址并调用它,但这仍然会使用各种条目修改您的注册表。如果您不想这样做(例如,您可能没有必要的权限来写入注册表),那么还有另一种方法。

任何包含一个或多个进程内 COM 对象的 DLL 都必须公开 DllGetClassObject 函数。此函数用于获取用于创建 COM 对象的 COM 类工厂的实例。你需要做的是:

  1. 加载包含所需 COM 对象的库 (DLL)
  2. 找到DllGetClassObject函数
  3. 调用 DllGetClassObject,将所需 COM 对象的 CLSID 传递给它,这将返回一个 IClassFactory 实例。
  4. 调用类工厂的 CreateInstance 方法来获取 COM 对象的实例。
  5. 将返回的对象转换为您希望使用的接口(interface)。

请注意,有些龙采用这种方法——它的等级相当低。如果您出错,您将遇到访问冲突异常或更糟的情况。 (例如,您的接口(interface)声明必须与 COM 接口(interface)完全匹配)。

我在 gist 中包含了一些示例代码如果您想这样做,您可能会喜欢使用它。

使用这段代码看起来像这样:

// Load the library. You dispose this after you are finished with
// all of your COM objects.
var library = new LibraryModule();
library.Load("mylibrary.dll"); or whatever your dll is called

var clsid = new Guid("75E81043-CAD5-11D3-800D-00105A5E2FA0");

var myObject = (MyInterface)ComHelper.CreateInstance(library, clsid);

请注意,如果您释放 LibraryModule 对象,那么这将卸载 DLL。根据您的需要,您可以将值分配给静态字段,以便它在程序的生命周期内存在。

关于c# - 在不注册 DLL 的情况下通过 ComInterop 在 C# 中编码(marshal)非托管 dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8752121/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com