c# - 将 (V)C++ long* 转换为 C# Int32* 的安全方法?

标签 c# c++ c++-cli

我目前正在用 C++/CLI 编写一个 DLL,它将充当非托管程序和另一个 C# DLL 之间的“代理”。调用程序需要我的“代理 DLL”来实现将由非托管程序调用的各种过程。到目前为止,没问题。

但是:其中一个函数具有以下原型(prototype):

extern "C" __declspec ( dllexport ) long Execute(unsigned long command, long nInBytes, byte bInData[], long nOutBytes, long* pnUsedOutBytes, byte bOutData[])

好吧,我的代理 DLL 只是调用提供以下函数原型(prototype)的 C# DLL(调用程序的文档也给出了它):

unsafe public UInt32 Execute(UInt32 command, Int32 nInBytes, byte* pInData, Int32 nOutBytes, Int32* pnUsedOutBytes, byte* pOutData);

编译器在参数 5 pnUsedOutBytes 处抛出错误 (C2664) 并告诉我,long* 无法转换为 int*。好吧,longint 目前有相同的实现,可能会在未来的某个时候改变,所以抛出的错误是可以理解的(尽管非指针 long 使用确实不抛出错误?)。

回到实际问题:调用我的 C# 函数的最佳解决方案是什么?我已经读过(当然)最好的解决方案是在调用 .NET 函数时使用 .NET 类型。所以:在调用函数时进行简单的类型转换是否安全,或者在任何不好的情况下这种类型转换都不起作用?

使用这一行可以让编译器冷静下来,但它真的安全吗?

curInstance->Execute(command, nInBytes, pInData, nOutBytes, (System::Int32*)pnUsedOutBytes, pOutData);

提前致谢!

最佳答案

不,不要使用那个类型转换。假设 pnUsedOutBytes 的实际值大于 2^32。最好的情况是,对 Execute 的调用会覆盖低字节并保留高于 32 位的位,从而导致错误的答案。

解决方案是使用指向 32 位数据类型的指针调用 Execute。在您的代理中创建一个,如果需要,给它一个合理的起始值,进行调用,并将结果值复制到 pnUsedOutBytes 指向的 long 中。

哦,不要解释错误信息。错误信息没有说你不能cast long* to int*;你可以。几乎可以肯定的是,编译器无法将 long*convertint*。没错:这两种类型之间没有隐式 转换。添加强制转换告诉编译器去做;这样你就有了一个显式转换。

关于c# - 将 (V)C++ long* 转换为 C# Int32* 的安全方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19496526/

相关文章:

c# - 为什么 Ldvirtftn 无法验证?

c++ - 在 C++ 中堆重载和读取文件的二维矩阵

c# - 找不到类型或命名空间名称 'Column'

c++ 指向引用的指针

c++ - 带函数指针的模板推导还原

c++ - 当我收到此错误 : <mutex> is not supported when compiling with/clr 时如何实现非托管线程安全集合

c++ - 捕获模板化异常时的编译器错误

c# - 收集在设计中创建的文本框

c# - 在 XNA 中检测运行时游戏平台