3

C# からアンマネージ VB COM dll を呼び出す際に問題があります。これは、loadLibrary と GetProcAddress を使用した動的呼び出しです。

loadLibrary を使用して dll を正常にロードできますが、 GetProcAddress は常に 0 を返します。エラー メッセージは記録されず、何も記録されませんでした。0 を返すだけです。

サンプルコードの下

VBコム

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が登録されていない場合、方法はありますか?

4

1 に答える 1

0

GetProcAddress オブジェクトと COM オブジェクトの概念は、まったく異なるテクノロジであることに注意してください。VB6 は COM オブジェクトを構築するように設計されており、(私の知る限り) GetProcAddress API を介してコードをエクスポートすることはできません。

また、設計上、COM オブジェクトはどこかに登録する必要がありますが、この情報をレジストリの代わりにマニフェスト ファイルに入れることは可能です。これは、グローバル レジストリを使用せずに、アプリケーション専用の VB6 COM クラスを登録できることを意味します。(マニフェストは、ファイルではなく .exe に埋め込むこともできることに注意してください。)

詳細については、「登録不要の COM」を検索してください。対応するMSDN の記事へのリンクは次のとおりです。

于 2011-01-19T07:27:30.297 に答える