Jump to content

DLLCallbackRegister application crash in X86 but not in X64


Go to solution Solved by TheXman,

Recommended Posts

Hello everyone,

I'm writing a small program that uses an external dll called "EAPI.dll". The SDK provides a 32 bits version and a 64 bits version of that DLL.

The 64 bits version works fine. However, the 32 bits version results in an application crash.

The 32 bits version:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <MsgBoxConstants.au3>
#include <AutoItConstants.au3>
#include <GUIConstantsEx.au3>

Global $aResult
Global $hEAPIdll
Global $IsRunning=True

Global $sIPSrawDataReturned
Global $iIPStypeReturned

HotKeySet("{ESC}","_Terminate") ;Press ESC key to terminate

;the EAPI.dll functions provided by Advantech
$hEAPIdll = DllOpen("D:\EAPI\X86\EAPI.dll")

If ($hEAPIdll = -1) Then
    MsgBox($MB_ICONERROR+$MB_OK,"IPS-AE Fatal Error","Error while opening EAPI.dll.")
    Exit
EndIf

;Create the callback function for EApiUPSInitDev.
Local $hAtCallback = DllCallbackRegister("_getIPSAEdata", "none", "int;str")

$aResult = DllCall($hEAPIdll, "DWORD", "EApiUPSInitDev", _
        "str", "COM1", _
        "ptr", DllCallbackGetPtr($hAtCallback))

While $IsRunning
    Sleep(100)
WEnd

Func _Terminate()
    $IsRunning=False
    DllClose($hEAPIdll)
    DllCallbackFree($hAtCallback)
EndFunc

; Callback Procedure
Func _getIPSAEdata($type, $str)
    ConsoleWrite("$type: " & $type & @CRLF)
    ConsoleWrite("$str: " & $str & @CRLF)
EndFunc   ;==>_getIPSAEdata

The 64 bits version:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <MsgBoxConstants.au3>
#include <AutoItConstants.au3>
#include <GUIConstantsEx.au3>

Global $aResult
Global $hEAPIdll
Global $IsRunning=True

Global $sIPSrawDataReturned
Global $iIPStypeReturned

HotKeySet("{ESC}","_Terminate") ;Press ESC key to terminate

;the EAPI.dll functions provided by Advantech
$hEAPIdll = DllOpen("D:\EAPI\X64\EAPI.dll")

If ($hEAPIdll = -1) Then
    MsgBox($MB_ICONERROR+$MB_OK,"IPS-AE Fatal Error","Error while opening EAPI.dll.")
    Exit
EndIf

;Create the callback function for EApiUPSInitDev.
Local $hAtCallback = DllCallbackRegister("_getIPSAEdata", "none", "int;str")

$aResult = DllCall($hEAPIdll, "DWORD", "EApiUPSInitDev", _
        "str", "COM1", _
        "ptr", DllCallbackGetPtr($hAtCallback))

While $IsRunning
    Sleep(100)
WEnd

Func _Terminate()
    $IsRunning=False
    DllClose($hEAPIdll)
    DllCallbackFree($hAtCallback)
EndFunc

; Callback Procedure
Func _getIPSAEdata($type, $str)
    ConsoleWrite("$type: " & $type & @CRLF)
    ConsoleWrite("$str: " & $str & @CRLF)
EndFunc   ;==>_getIPSAEdata

In the console, I can see that the callback function has been called by the DLL, but ~5 seconds later, AutoIT crashes.

Here is the provided CPP example for the DLL functions I'm trying to use in AutoIT:

// IPS-AE_Sample.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include "atIPSAE.h"
#include "atEAPI.h"


using namespace std;
using namespace EApiCommonDLL;

HINSTANCE hDLL = NULL;

void atCallBack(CallBackType type, char* str)
{
	printf("======================\ntype: %d\n%s\n==========================\n", type, str);
};


void setTimetoDev(int t1, int t2)
{
	if(hDLL)
	{
		EAPIFunction(hDLL, EApiUPSSetDCinLostDelayTime);
		if(EApiUPSSetDCinLostDelayTime){
			char response[0xff] = {0};
			unsigned int res = EApiUPSSetDCinLostDelayTime(t1, response, 0xff);
			if(res == 0)printf("setDCinLostDelayTime result => %s\n", response);
		}

		EAPIFunction(hDLL, EApiUPSSetDCoutCutOffDelayTime);
		if(EApiUPSSetDCoutCutOffDelayTime){
			char response[0xff] = {0};
			unsigned int res = EApiUPSSetDCoutCutOffDelayTime(t2, response, 0xff);
			printf("setDCoutCutOffDelayTime result => %s\n", response);
		}
	}
}

void runIPS_AE(char* comport)
{
	hDLL = OpenEAPI();
	if (hDLL == NULL)
	{
		printf("EAPI.dll Load Failed! 0x%X\n", GetLastError());
		return;
	}
	EAPIFunction(hDLL, EApiUPSInitDev);
	//AdvIPSAEOBJ pobj = (AdvIPSAEOBJ)GetProcAddress(hDLL, "getAdvIPSAE");
	if (EApiUPSInitDev != NULL)
	{
		if(!EApiUPSInitDev(comport, (IPSAEResopne)atCallBack))
		{
			printf("start, there will send a callback automatically.....\n");
			getchar();
			setTimetoDev(300, 5);
		}
	}
	else
	{
		printf("GetProcAddress \"getAdvIPSAE\" Failed! 0x%X\n", GetLastError());
	}

}

void byeIPS_AE()
{
	if (hDLL)
	{
		//delAdvIPSAE delpobj = (delAdvIPSAE)GetProcAddress(hDLL, "AdvIPSAE::delAdvIPSAE");
		//delAdvIPSAE delpobj = (delAdvIPSAE)GetProcAddress(hDLL, "delAdvIPSAE");
		EAPIFunction(hDLL, EApiUPSDeinitDev);
		if (EApiUPSDeinitDev != NULL)
		{
			EApiUPSDeinitDev();
			Sleep(1000);
			CloseEAPI(hDLL);
		}
	}
}

int main(int argc, char* argv[])
{
	if(argc < 2)
	{
		printf("example: IPS-AE_Sample.exe COM1\n");
		return -1;
	}

	runIPS_AE(argv[1]);
	getchar();
	byeIPS_AE();

	return 0;
}

Does somebody have a clue on what's going on ? I would appreciate any suggestion.

I've put the DLLs in the attached files and also some screenshots of the developper guide provided with the SDK.

Thank you for your help

+++

eapi_dll_guide_1.png

eapi_dll_guide_2.png

EAPI.rar

Link to comment
Share on other sites

  • Solution

Assuming that everything else is correct, the most common reason for an immediate crash, when executing in 32bit mode, is that your APIs use the cdecl calling convention.  By default, AutoIt uses stdcall.  So you need to add ":cdecl" to all of your return data types.  example: 

$aResult = DllCall($hEAPIdll, "DWORD:cdecl", "EApiUPSInitDev", _
        "str", "COM1", _
        "ptr", DllCallbackGetPtr($hAtCallback))

Read more about it in the DllCall help file topic.

You can leave the :cdecl when running in 64bit mode, it'll be ignored.

 

Edited by TheXman
Link to comment
Share on other sites

We've all been there.  ;)

You're welcome.  :)

Edited by TheXman
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...