[英]Can this COM interface be implemented in C#?
COM 組件目前是用 C++ 實現的,下一個版本必須用 C# 實現。 該組件是從 C++(不是 CLI)代碼調用的。 不是那么小的組件的主要部分已經移植到 C#,但我很難弄清楚如何翻譯一種特定的方法。
IDL 中使用了以下導入:
import "oaidl.idl";
import "ocidl.idl";
接口的主要部分已經轉換為相應的 C# 屬性、接口和類。 它的大部分工作沒有問題。
但是接口成員之一在 IDL 中定義為
[
object,
uuid(<guid>),
helpstring("Help"),
pointer_default(unique)
]
interface IStuff : IUnknown
{
...
HRESULT GetShortText([in] int i, [in] BOOL b, [out, string] TCHAR shortText[10]);
...
}
要使用該接口,將本地TCHAR[10]
數組作為數組的名稱(因此,作為TCHAR*
)傳遞。 COM 服務器必須在 TCHAR 數組中放置一個短字符串。
我無法調用該方法。 在 C# COM 服務器中GetShortText
方法中設置的斷點永遠不會被命中。 COM 根本沒有在 .NET 中找到我的實現。
這個以固定大小TCHAR*
調用的方法如何在 C# 中正確實現?
我不知道這個相當不尋常的構造有任何標准編組。 但是,您可以執行以下操作:
void GetShortText(int i, [MarshalAs:UnmanagedType.Bool] bool b, IntPtr shortTextPtr)
{
string s = "Test";
byte[] buffer;
if (UseUnicode)
buffer = Encoding.Unicode.GetBytes(s + '\0');
else
buffer = Encoding.Default.GetBytes(s + '\0');
Marshal.Copy(buffer, 0, shortTextPtr, buffer.Length);
}
筆記:
+ '\\0'
用於空終止返回的字符串通過將參數指定為IntPtr
並手動編組字符串,可以在 .Net 中實現這種接口。 可以在 Github上找到完整的演示。
示例實現:
[ComVisible(true), Guid("E559D616-4C46-4434-9DF7-E9D7C91F3BA5"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStuff
{
void GetShortTest(int i, [MarshalAs(UnmanagedType.Bool)] bool b, IntPtr shortText);
}
[ComVisible(true), ProgId("InProcTargetTest.Class1"), Guid("BA5088D4-7F6A-4C76-983C-EC7F1BA51CAA"), ClassInterface(ClassInterfaceType.None)]
public class Class1 : IStuff
{
public void GetShortTest(int i, bool b, IntPtr shortText)
{
var data = Encoding.Unicode.GetBytes("Hello");
Marshal.Copy(data, 0, shortText, data.Length);
}
}
示例調用者:
if (FAILED(CoInitialize(nullptr))) {
std::cout << "Failed to initialize COM\n";
}
IStuff *pStuff = nullptr;
CLSID clsClass1 = { 0 };
if (FAILED(CLSIDFromProgID(L"InProcTargetTest.Class1", &clsClass1))
|| FAILED(CoCreateInstance(clsClass1, nullptr, CLSCTX_INPROC_SERVER, IID_IStuff, (LPVOID*)&pStuff))) {
std::cout << "Failed to create COM instance\n";
}
TCHAR test[10] = { 0 };
pStuff->GetShortTest(5, true, test);
std::cout << "From C#: " << test << "\n";
示例 IDL:
import "unknwn.idl";
[
odl,
uuid(E559D616-4C46-4434-9DF7-E9D7C91F3BA5),
version(1.0),
pointer_default(unique),
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "InProcTargetTest.IStuff")
]
interface IStuff : IUnknown {
HRESULT _stdcall GetShortTest(
[in] long i,
[in] BOOL b,
[out, string] TCHAR shortText[10]);
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.