I run into the problem while trying to link to C++ with ptr DWORD. What would that be in the C++ function call?



FindArray proc, findie:DWORD, arrie:ptr DWORD, stopie:DWORD
push ebp
mov ebp, esp
push ecx
push edx
push edi

mov ecx, stopie
mov eax, findie
cld
repne scasd
cmp ecx, 0
JE NotFound
sub edi, type dword
jmp end_search

NotFound: mov edi, 0
end_search: mov eax, edi

pop edi
pop edx
pop ecx
pop ebp
ret
FindArray endp

C++:
#include <iostream>
using namespace std;

extern "C" int FindArray(int FindThis, int *Array, int ArrSize );

int main()
{
int tester[11];
int *ptrFound;

for(int t=0; t<11; t++)
tester[t]=t;

ptrFound = FindArray(3,tester,10);

cout << *ptrFound;

return 0;

}

Posted on 2004-12-08 18:26:07 by sjaguar13
You need to use the 'PUBLIC' directive (assuming you're using masm). If you're using nasm you need to use the 'GLOBAL' directive. These directives change the scope of the symbol.
Posted on 2004-12-08 22:10:50 by nohaven
I have this at the top of my ASM.

.386

.MODEL FLAT,C

Public FindArray


.CODE
Posted on 2004-12-08 23:30:43 by sjaguar13
What is the link error you're getting? It is possible that you may need to decorate the symbol name (add an underscore to the front of it), though I'm not sure whether or not masm does this natively for you or not (not my primary assembler).
Posted on 2004-12-08 23:34:57 by nohaven
Using the ,C after .MODEL FLAT eleminates the _ thing. I am getting cannot convert parameter 2 from 'int [11]' to 'int &'. I believe they are linked right, I just don't know how to call it because of the PTR DWORD that's needed. What is that in C?
Posted on 2004-12-08 23:47:47 by sjaguar13
I see -- so this isn't a linking problem (misunderstood your issue due to it being referenced as a linker error). What compiler are you using? One problem is that you have the prototype declared as returning a 'int' but you're assigning it to a pointer to an int. This would not explain the error regarding parameter two (though I don't see how you could be getting that error with the code you provided). Try changing the prototype to return a pointer to an int.

Posted on 2004-12-08 23:56:27 by nohaven
Change it to int & FindArray? Should the second parameter be int &tester and I pass in tester, or should it be something else?
Posted on 2004-12-09 00:27:34 by sjaguar13
It should be:



#include <iostream>
using namespace std;

extern "C" int *FindArray(int FindThis, int *Array, int ArrSize );

int main()
{
int tester[11];
int *ptrFound;

for(int t=0; t<11; t++)
tester[t]=t;

ptrFound = FindArray(3,tester,10);

cout << *ptrFound;

return 0;

}


Note the change in the prototype. The above code compiles fine for me with VC++ 6.0. You should not use the '&' operator because that indicates that the parameter, return value, or variable is being used as a reference which has subtle semantic differences between native pointers.
Posted on 2004-12-09 00:32:57 by nohaven
It compiles, but it crashes as soon as I run it.



.386
.MODEL FLAT,C

Public FindArray


.CODE ; start of main program code

FindArray proc, findie:DWORD, arrie:ptr DWORD, stopie:DWORD
push ebp
mov ebp, esp
push ecx
push edx
push edi

mov ecx, stopie
mov eax, findie
mov edi, arrie
cld
;repne scasd
;cmp ecx, 0
;JE NotFound
;sub edi, type dword
;jmp end_search

;NotFound: mov edi, 0
;end_search: mov eax, edi

pop edi
pop edx
pop ecx
pop ebp
ret
FindArray endp


END ; end of source code


I have to comment that stuff out for it run and not crash. Is it not loading the address properly?
Posted on 2004-12-09 00:44:53 by sjaguar13
use ollydbg to check where the crash accours, most likely to be at instruction repne scasd but check in debugger
Posted on 2004-12-09 01:01:09 by wizzra
It doesn't like repne scasd. That's why I am thinking the address wasn't loaded right.
Posted on 2004-12-09 01:07:26 by sjaguar13
There are a few issues with the FindArray implementation you're using. You don't need to worry about preserving ecx and edx per ABI specification and the method being used to differentiate between not found and found will not work (NotFound falls through to end_search). Furthermore, I'm not sure that masm implicitly knows to make the arguments you supplied to the procedure definition relative to the frame pointer instead of the stack pointer (which could in turn lead to the crash you're experiencing). The following code illustrates explicitly referencing the arguments based on their relation to the frame pointer:



FindArray:
push ebp
mov ebp, esp
push edi
mov ecx, [ebp + 0x10]
mov edi, [ebp + 0xc]
mov eax, [ebp + 0x8]
cld
repnz scasd
xor eax, eax
test ecx, ecx
jz NotFound
lea eax, [edi - 0x4]

NotFound:
pop edi
mov esp, ebp
pop ebp
ret
Posted on 2004-12-09 01:08:55 by nohaven
One of the return values is 0, but there is no test for NULL in the posted code. *NULL is an invalid memory reference.
Posted on 2004-12-09 01:47:58 by tenkey