我正在调用的函数是一个不能被PInvoked的模糊API的一部分,因为库的唯一入口点是指向其中函数的指针结构。话虽这么说,我有结构和C ++实现示例代码。
tl; dr我不是PInvoking这个函数。
以下是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
答案 0 :(得分:0)
这一切都归结为你试图调用的函数的契约,你没有告诉我们很多:它应该返回一个字符,一个字节,一个位,一个布尔值?
如果您要调用的函数应该返回一个字符,那么您应该期望chr(48)
和chr(49)
。但显然,你没有收到一个。不要注意内部使用char
的事实:char
用于旧式C代码,而不是字节,位和布尔值。因此,您必须遵循某种规范,而不是试图对其他人的代码的内部进行文字读取。
在C语言系列中,if()
语句检查某些内容是零(FALSE
)还是非零(TRUE
)。因此,当某些内容被评估为TRUE
时,它不必等于1
,它可以是任何非零值。实际上,-1
并不罕见。
所有1
s的位模式都是非零值,因此如果将其作为布尔值检查,则它对应于TRUE。 (并且在两个补码中,所有1
s的位模式实际上是-1
。)因此,您调用的函数很可能应该返回一个布尔值,而您实际上是收到TRUE
。
(当然,鉴于此,像if( u1Val == 1 )
这样的代码有点奇怪,应该是if( u1Val != 0 )
,所以可能会有一些可疑的东西。)