c# - 函数的 IDL 声明(在 C++ 中)将从 C# 获取 C 样式数组

标签 c# c++ com idl

我正在使用一个现有代码库,该代码库由一些用 C++ 编写的带有 C# 前端的 COM 接口(interface)组成。有一些新功能需要添加,所以我不得不修改 COM 部分。在一种特殊情况下,我需要将一个数组(从 C# 分配)传递给要填充的组件。

我想做的是能够将一个 int 数组传递给 C# 中的方法,例如:

// desired C# signature
void GetFoo(int bufferSize, int[] buffer);

// desired usage
int[] blah = ...;
GetFoo(blah.Length, blah);

工作中的几个 Spanner :

  • 不能使用 C++/CLI 或托管 C++(在这种情况下可以取消 COM)。
  • C# 端不能用/unsafe 编译(允许使用 Marshal)。

COM 接口(interface)仅由 C# 部分使用(并且永远只会使用),因此我不太关心与其他 COM 使用者的互操作性。 32 位和 64 位之间的可移植性也不是问题(一切都在 32 位机器上编译和运行,因此代码生成器将指针转换为整数)。最终,它将仅被 C++/CLI 取代,但这还有很长的路要走。


我的初步尝试

类似于:

HRESULT GetFoo([in] int bufferSize, [in, size_is(bufferSize)] int buffer[]);

并且输出的TLB定义是(貌似合理):

HRESULT _stdcall GetFoo([in] int bufferSize, [in] int* buffer);

这是由 C# 导入的(不太合理):

void GetFoo(int bufferSize, ref int buffer);

可以使用

int[] b = ...;
fixed(int *bp = &b[0])
{
    GetFoo(b.Length, ref *bp);
}

...除了我无法使用/unsafe 进行编译。


此刻

我正在使用:

HRESULT GetFoo([in] int bufferSize, [in] INT_PTR buffer);

导入为:

void GetFoo(int bufferSize, int buffer);

我需要像这样使用它:

int[] b = ...;
GCHandle bPin = GCHandle.Alloc(b, GCHandleType.Pinned);
try
{
    GetFoo(b.Length, (int)Marshal.UnsafeAddrOfPinnedArrayElement(b, 0));
}
finally
{
    bPin.Free();
}

哪个有效...,但我想找到一种更简洁的方法。


所以,问题是

在这种情况下,是否有对从 TLB 生成器导入 C# 友好的 IDL 定义?如果不是,在 C# 端可以做些什么来让它更安全一些?

最佳答案

因此,您要求 IDL 数据类型在 32 位机器上为 32 位,在 64 位机器上为 64 位。但是您不希望编码(marshal)处理代码将其视为指针,只是作为 int。那么,当您从 64 位进程调用 32 位进程时,您希望额外的 32 位发生什么情况?

对我来说这听起来像是违反物理学的。

如果它只是 inproc,请参阅此讨论的底部:http://www.techtalkz.com/vc-net/125190-how-interop-net-client-com-dll.html .

建议似乎是使用 void * 而不是 intptr 并用 [local] 标记,这样编码器就不会参与。

关于c# - 函数的 IDL 声明(在 C++ 中)将从 C# 获取 C 样式数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/199629/

相关文章:

c# - “不存在数据时读取无效”错误

c# - 多个异步操作需要另一个异步结果

c++ - 如何使用具有 C++0x 特性的 autoconf

c# - 如何检索 SQL Server LocalDb 名称列表?

c++ - 如何使用Windows api中的参数执行线程?

c++ - 用输入表示数组中元素的数量吗?

c# - 有没有办法注册免激活EXE COM组件

c++ - DLL 中的 outproc COM 服务器

c++ - 将程序输出传递给 DirectShow 源过滤器以供 Lync 获取?

c# - 如何拆分分隔符保留在结果末尾的字符串?