通过ComInterop在C#中封送非托管dll而不注册dll
我有一个非托管DLL,目前正在使用COM类包装器从C#调用它通过ComInterop在C#中封送非托管dll而不注册dll,c#,marshalling,com-interop,unmanaged,C#,Marshalling,Com Interop,Unmanaged,我有一个非托管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 MyInt
[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");
这是可行的,返回值与我预期的一样。但是,它需要使用regsvr32注册dll
我正在寻找一种不需要regsvr32的方法来实现这一点。最好是只提供dll的副本。值得注意的是,我有非托管dll的源代码,并且能够在必要时对其进行修改
如果您的DLL必须是COM对象,则必须进行注册。此注册不需要由regsvr32执行。regsvr32所做的就是加载DLL,获取DllRegisterServer的地址并调用它。DllRegisterServer向注册表添加应用程序使用该对象所需的条目
如果您的DLL不需要是COM对象,您可以对其进行修改,只需导出所需的函数并p调用即可。您需要为免注册COM设置非托管DLL。这是一个非常完整的例子。其中包括使用清单指向文件、并行程序集和一些互操作
演练中的一个重要注意事项是,客户机的初始设置需要注册,但以后不需要注册 我也想自己做同样的事情。正如Jim提到的,可以获取
DllRegisterServer
的地址并调用它,但这仍然会使用各种条目修改注册表。如果您不想这样做(例如,您可能没有写入注册表所需的权限),那么还有另一种方法
任何包含一个或多个进程内COM对象的DLL都必须公开DllGetClassObject
函数。此函数用于获取用于创建COM对象的COM类工厂的实例。您需要做的是:
DllGetClassObject
函数DllGetClassObject
,将所需COM对象的CLSID传递给它,这将返回一个IClassFactory
实例CreateInstance
方法以获取COM对象的实例// 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。根据您的需要,您可以将该值分配给一个静态字段,使其在程序的整个生命周期内都存在。这可能会有所帮助:我有很多阅读工作要做,但我会尝试一下。谢谢。PInvoke方法会很棒,只是dll api远没有我的示例那么简单。我的问题更多的是它必须通过外部方法注册。。。Boo的建议可能是我最后的选择,不太准确。有这样一件事,可能就是为了这个。这正是我所希望的。谢谢,你好。感谢您提供了非常有趣的解决方案。但是,当我尝试使用您的代码时,它无法说明加载的dll中不存在DllGetClassObject。我加载的dll是一个.net 4程序集,已选中“Register for COM interop”,并为接口和类使用了正确的(我猜)属性。你能帮忙吗?