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;
}
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.
I have this at the top of my ASM.
.386
.MODEL FLAT,C
Public FindArray
.CODE
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).
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?
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.
Change it to int & FindArray? Should the second parameter be int &tester and I pass in tester, or should it be something else?
It should be:
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.
#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.
It compiles, but it crashes as soon as I run it.
I have to comment that stuff out for it run and not crash. Is it not loading the address properly?
.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?
use ollydbg to check where the crash accours, most likely to be at instruction repne scasd but check in debugger
It doesn't like repne scasd. That's why I am thinking the address wasn't loaded right.
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
One of the return values is 0, but there is no test for NULL in the posted code. *NULL is an invalid memory reference.