通过.NET中的指针从本机方法返回数据
本文关键字:本机 方法 返回 数据 指针 NET 通过 | 更新日期: 2023-09-27 18:25:59
我调用的函数是一个模糊的API的一部分,该API无法PInvoked,因为库的唯一入口点是指向其中函数的指针结构。话虽如此,我有C++的结构和实现示例代码。
tl;dr我不想看这个功能。
以下是C++中的实现情况
// Definition
extern "C" typedef short (* GETBIT)(short,char*);
// Base function for using API
void anApi::GetData(short index, void* pData)
{
switch(internal logic...)
{
case bitData:
get_bit(index, (char *)(pData));
case (other data types)...
}
}
// Higher level API implementation
UCHAR u1Val = 0;
GetData( 1234, &u1Val );
if( u1Val == 1 )
{
doSomthing();
}
大概我应该返回0或1(即使实际的数据类型是这样的)。我应该提到API有错误检查,为了简单起见,我省略了它,并且我的代码不会导致任何错误。还有一个初始化函数成功了,所以我知道我调用这些函数是正确的。
以下是我如何在C#中实现相同的功能
// Definition
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate short get_bit_delegate(short index, out byte data);
get_bit_delegate get_bit;
// Base function
public string GetDataBit(short index)
{
string ReturnData = "test";
// Using .NET type of Byte instead of char...
byte myByte = 0;
lRetCode = get_bit(index, out myByte);
// get a good look at what we returned
ReturnData = Convert.ToString(myByte, 2).PadLeft(8, '0');
return ReturnData;
// error checking snipped for brevity
}
// Implementation
textBox1.Text = GetDataBit(1234);
我尝试过不同的数据类型,包括IntPtr和Marshaling,但我一直得到相同的结果:
11111111(ï)
他们在示例代码中使用结果的方式,我认为返回值应该是"1"或"0"。事实上,在我的测试用例中,我希望看到0。
0-chr(48)-00110000
1-chr(49)-00110001
这一切都可以归结为您试图调用的函数的契约,您没有告诉我们太多:它应该返回一个字符、一个字节、一个位、一个布尔值吗?
如果您正在调用的函数应该返回一个字符,那么您应该期望chr(48)
和chr(49)
。但很明显,你没有收到。不要注意char
在内部使用的事实:char
在旧式C代码中代替了字节、位和布尔值。因此,你必须遵循某种规范,而不是试图对其他人的代码内部进行字面解读。
在C族语言中,if()
语句检查某个东西是零(FALSE
)还是非零(TRUE
)。因此,当某个值被假定为TRUE
时,它不必等于1
,它可以是任何非零值。实际上,-1
并不罕见。
所有1
s的位模式都是非零值,因此如果将其检查为布尔值,则它对应于TRUE。(在2的补码中,所有1
s的位模式实际上是-1
。)因此,很可能您正在调用的函数应该返回布尔值,而实际上您正在接收TRUE
。
(当然,鉴于此,像if( u1Val == 1 )
这样的代码有点奇怪,它应该是if( u1Val != 0 )
,所以可能有什么可疑之处。)