从C#动态调用未经管理的VB COM DLL存在问题?

3

我有一个问题,需要从C#中调用未托管的VB COM dll。这是使用loadLibrary和GetProcAddress进行动态调用。

我成功地使用loadLibrary加载了dll,但是GetProcAddress始终返回0。它没有记录任何错误消息,什么都没有。它只返回0。

以下是示例代码:

VB COM

VERSION 1.0 CLASS
BEGIN
    MultiUse = -1 
    Persistable = 0  
    DataBindingBehavior = 0  
    DataSourceBehavior  = 0 
    MTSTransactionMode  = 0  
END

Attribute VB_Name = "Sample"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True

Option Explicit

Private Attribute1 As String
Private Sub Class_Initialize()
    Attribute1 = "test"
End Sub

Public Sub TestSub()

End Sub

Public Function testFunction() As String
    testFunction = "default.html"
End Function

Public Function SetData(XML As String) As String
    SetData = Date + Time
End Function

c# 代码

static class UnManagedInvoker
{
    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string dllToLoad);

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procedureName);

    [DllImport("kernel32.dll")]
    private static extern bool FreeLibrary(IntPtr hModule);

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate string MethodToInvoke(string sdata);

    public static string InvokeUnmanagedDll(string dllPath, string methodName)
    {
        IntPtr DIedDll = LoadLibrary(dllPath);

        IntPtr AddressOfFunction = GetProcAddress(DIedDll, methodName);

        MethodToInvoke MI = (MethodToInvoke)Marshal.GetDelegateForFunctionPointer(AddressOfFunction, typeof(MethodToInvoke));

        string data = MI("ssdasda");

        FreeLibrary(DIedDll);
        return data;

    }
}

调用代码

 string res = UnManagedInvoker.InvokeUnmanagedDll("xx.dll","SetData");

请问有人能帮助我吗...

更新:

如果组件已经注册,我可以成功调用方法,使用以下代码

Type Med = Type.GetTypeFromCLSID(new Guid("089DD8B0-E12B-439B-B52C-007CA72C93D0"));
object MedObj = Activator.CreateInstance(Med);
object[] parameter = new object[1];
parameter[0] = "asdasd";
var ss = Med.InvokeMember("SetData", System.Reflection.BindingFlags.InvokeMethod, null, MedObj, parameter);

有没有一种方法可以在DLL未注册的情况下使用它?
1个回答

0
请注意,GetProcAddress和COM对象的概念是完全不同的技术。VB6旨在构建COM对象,据我所知,无法通过GetProcAddress API导出代码。
此外,按设计,COM对象需要在某个地方注册,但可以将此信息放入清单文件中,而不是注册表中。这意味着您可以仅为应用程序注册您的VB6 COM类,而无需使用全局注册表。(请注意,清单也可以嵌入到.exe中,而不是作为文件。)
有关更多信息,请搜索“Registration free COM”,以下是相应MSDN文章的链接。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接