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