All,
Thanks for all of your answers on this. I really appreciate it. I was unaware of the “strcpy” memory allocation requirements. I will take another look at that. Also (majidkamali1370) I did see some online sites that talked about the method you describe. I’m going to check that way out also. If it is easier, I’ll do it that way.
The ASM routine creates a string in memory that I need to (somehow) transfer to C++ and then back to my VB program. I think I can do that by using the ASM memory pointer?
After sending the initial message, I did some more research and found this web site:
http://www.codeproject.com/KB/DLL/XDllPt2.aspx
Using the instructions it contained, I was able to make a working DLL that I could call from VB. I used their test function initially then plugged my ASM code back in. When I did that I started getting errors again so I probably fat fingered something. I pasted a copy of the errors below.
One of the problems I had was that I needed to make a .DEF file and I needed to include a “.h” file with the same name as the .DLL I created. I also had to add “__stdcall” in the procedure/function.
One interesting thing is that I can only (seemingly) create a reference to one routine at a time in the C++ DLL. As it looks right now, I can’t seem to create a reference to the whole thing and call whatever routine I want. So if the DLL has 100 routines, I’ll have to make individual references to each.
I
Deleting intermediate files and output files for project 'testdll - Win32 Debug'.
--------------------Configuration: testdll - Win32 Debug--------------------
Compiling...
StdAfx.cpp
Compiling...
testdll.cpp
C:\VB6 programs\Devstudio 9A\cplus_proj\testdll\testdll.cpp(12) : error C2143: syntax error : missing ';' before 'using'
C:\VB6 programs\Devstudio 9A\cplus_proj\testdll\testdll.cpp(12) : warning C4229: anachronism used : modifiers on data are ignored
C:\VB6 programs\Devstudio 9A\cplus_proj\testdll\testdll.cpp(41) : error C2491: 'GetCpuSpeed' : definition of dllimport function not allowed
C:\VB6 programs\Devstudio 9A\cplus_proj\testdll\testdll.cpp(49) : error C2373: 'DodgeCherokee' : redefinition; different type modifiers
C:\VB6 programs\Devstudio 9A\cplus_proj\testdll\testdll.cpp(12) : see declaration of 'DodgeCherokee'
C:\VB6 programs\Devstudio 9A\cplus_proj\testdll\testdll.cpp(49) : error C2491: 'DodgeCherokee' : definition of dllimport function not allowed
C:\VB6 programs\Devstudio 9A\cplus_proj\testdll\testdll.cpp(185) : error C2440: 'return' : cannot convert from 'char *' to 'int'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
C:\VB6 programs\Devstudio 9A\cplus_proj\testdll\testdll.cpp(188) : warning C4035: 'DodgeCherokee' : no return value
Error executing cl.exe.
testdll.dll - 5 error(s), 2 warning(s)
The current code:
// testdll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "stdio.h"
#include <string>
#include "windows.h"
#include "stdafx.h"
#include "testdll.h"
#define testdll_EXPORTS
using std::string;
//using namespace std;
// testdll.cpp : Defines the entry point for the DLL application.
//
BOOL APIENTRY DllMain( HANDLE /*hModule*/,
DWORD ul_reason_for_call,
LPVOID /*lpReserved*/
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// Example of an exported function
///////////////////////////////////////////////////////////////////////////////
// GetCpuSpeed - returns CPU speed in MHz; for example, ~2193 will be
// returned for a 2.2 GHz CPU.
testdll_API int __stdcall GetCpuSpeed()
{
Sleep(1000);
return 1000;
}
DodgeCherokee_API int __stdcall DodgeCherokee (LONG szMileage)
{
long Miles;
string ReturnString;
char * Mypointer;
__asm
{
// :00402B74 push 000003EA
// :00402B79 push esi
// :00402B7A call USER32.SendDlgItemMessageA
mov edx, dword ptr [esp+0x1C]
dec eax
dec eax
neg eax
sbb eax, eax
inc eax
push eax
push edx
push esi
// call PRO.004024C0
sub esp, 0x0000021C
push esi
// :004024C7 mov esi, dword ptr [esp+00000228]
mov esi, szMileage
cmp esi, 0x000F423F
// :004024D4 jbe 0040250D
//not going to check max here
// :004024D4 jmp PRO.0040250D
mov eax, esi
xor edx, edx
mov ecx, 0x00000064
push ebx
div ecx
mov eax, 0xD1B71759
mov eax, 0xD1B71759
push edi
mov bl, dl
mul esi
mov eax, edx
xor edx, edx
shr eax, 0x0D
div ecx
mov eax, 0x51EB851F
mov cl, dl
mul esi
mov eax, edx
xor edx, edx
shr eax, 05
mov esi, 0x00000064
mov esi, 0x00000064
mov byte ptr [esp+0x0C], cl
div esi
test dl, dl
mov byte ptr [esp+0x24], dl
// :0040254D je PRO.0040255B
dec dl
mov byte ptr [esp+0x10], cl
mov byte ptr [esp+0x20], dl
// :00402559 jmp PRO.00402571
mov edx, dword ptr [esp+0x0C]
mov esi, dword ptr [0x004080E4]
and edx, 0x000000FF
lea eax, dword ptr [esp+0x14]
push edx
push 0x0040A688
push 0x0040A688
push eax
// call USER32.wsprintfA
mov ecx, dword ptr [esp+0x30]
lea edx, dword ptr [esp+0x28]
and ecx, 0x000000FF
push ecx
push ecx
push 0x0040A688
push edx
// call USER32.wsprintfA
mov eax, dword ptr [esp+0x28]
lea ecx, dword ptr [esp+0x24]
and eax, 0x000000FF
push eax
push eax
push 0x0040A688
push ecx
// call USER32.wsprintfA
mov edx, dword ptr [esp+0x44]
lea eax, dword ptr [esp+0x3C]
and edx, 0x000000FF
push edx
push 0x0040A688
push 0x0040A688
push eax
// call USER32.wsprintfA
mov cl, byte ptr [esp+0x4D]
mov dl, byte ptr [esp+0x4C]
mov al, byte ptr [esp+0x44]
sub cl, 0x30
shl dl, 0x04
or cl, dl
mov dl, byte ptr [esp+0x45]
shr bl, 0x1
movzx di, bl
sub dl, 0x30
add esp, 0x00000030
shl al, 0x04
or dl, al
xor esi, esi
test di, di
mov byte ptr [esp+0x00000128], cl
mov byte ptr [esp+0x00000129], dl
mov eax, 0x00000002
// :00402613 jbe 00402648
mov esi, edi
and esi, 0x0000FFFF
mov edi, esi
PRO_0040261F: mov ebx, eax
and ebx, 0x0000FFFF
inc eax
mov byte ptr [esp+ebx+0x00000128], cl
mov ebx, eax
and ebx, 0x0000FFFF
inc eax
dec edi
mov byte ptr [esp+ebx+0x00000128], dl
jne PRO_0040261F
mov Mypointer,ecx
ret
}
return Mypointer;
}