Having problem dynamically invoking unmanaged VB COM dll from c#?

1k views Asked by At

I have a problem calling unmanaged VB COM dll from c#. This is dynamic invocation using loadLibrary and GetProcAddress.

I can successfully loaded the dll using loadLibrary , but the GetProcAddress always return 0. It wasnt log any error msg and nothing. it just returns 0.

below the sample code

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# code

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;

    }
}

And the calling code

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

Can someone help me out..

Update:

I can successfully call the methods if the component is registered. using the below code

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);

is there a way if the dll not registered.?

1

There are 1 answers

0
Zarat On

Note that the concept of GetProcAddress and COM objects are completely different technologies. VB6 is designed to build COM objects and (to my knowledge) is not able to export code via the GetProcAddress API.

Also by design COM objects need to be registered somewhere, it is however possible to put this information in a manifest file instead of the registry. This means you can register your VB6 COM classes only for your application without using the global registry. (Note that a manifest could also embedded into the .exe instead of being a file.)

For more information search for "Registration free COM", here's a link to the corresponding MSDN article.