C callbacks getting a value of 0! Bug in D?

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Aug 28 17:42:45 PDT 2017


On 8/28/17 7:47 PM, Johnson Jones wrote:
> On Monday, 28 August 2017 at 21:35:27 UTC, Steven Schveighoffer wrote:
>> On 8/27/17 10:17 PM, Johnson Jones wrote:
>>> Looking at the assembly shows something like this:
>>>
>>> 0041ea98  push 0x0
>>> 0041ea9a  push 0x0
>>> 0041ea9c  push 0x0
>>> 0041ea9e  push dword 0x100
>>> 0041eaa3  mov ecx, [typeid(PaStreamParameters)+0xe36fc (0x80d4cc)]
>>> 0041eaa9  mov eax, [fs:0x2c]
>>> 0041eaaf  mov edx, [eax+ecx*4]
>>> 0041eab2  push dword [edx+0x1c]
>>> 0041eab8  push dword [edx+0x18]
>>> 0041eabe  push dword [ebp-0x54]
>>> 0041eac1  push dword [ebp-0x5c]
>>> 0041eac4  mov ebx, PA.stream (0x823f30)
>>> 0041eac9  push ebx
>>> 0041eaca  call dword near [Pa_OpenStream (0x823f18)]
>>>
>>> I noticed that those 0's were the values being fed in to the function.
>>>
>>> I remember converting c_ulong's to ulong's and that they were 
>>> probably uint's in D. Converting those fixed the problem and the 
>>> callback is now called! I converted all the ulongs to uint's but 
>>> there were a few longs and I don't know if they are c_longs or 
>>> d_longs...
>>>
>>> Anyways, At least I'm on the right track.
>>>
>>
>> For C/C++ interaction, always use c_... types if they are available. 
>> The idea is both that they will be correctly defined for the width, 
>> and also it will mangle correctly for C++ compilers (yes, long and int 
>> are mangled differently even when they are the same thing).
>>
> 
> In portaudio, this doesn't seem to be the case. I changed all the longs 
> to ints and ran my code in x64 and it worked fine.
> 
> It may just be that the stuff that uses long is not used in my code. In 
> port audio I see it using unsigned long and so this should be 64-bits in 
> x64. Surprised it worked. Maybe conversion is taking place or the high 
> bits of the long are 0'ed and so there is not much difference.

Then I think possibly the port audio bindings are not correct. It's also 
possible that long is not 64-bit even on the platform you are using. 
Finally, it's also possible that the D compiler is not generating the 
call correctly.

When I test on my mac, c_long is 8-bytes. I'm not sure what it is in 
your case, try this code and see what happens:

import core.stdc.config;

pragma(msg, c_long.sizeof); // prints 8 on my box.

And in c:

#include <stdio.h>

int main()
{
    printf("%lu\n", sizeof(long)); // also prints 8 on my box
    return 0;
}

They should match. If they don't, that's a D bug (in either 
core.stdc.config or the compiler, I'm not sure which). If they do, then 
one of the other two possibilities is happening, and I would lean 
towards the bindings being incorrect.

-Steve


More information about the Digitalmars-d-learn mailing list