![]() |
Hilfe bei einem Callback einer C++ Dll nach Delphi
Dll Callback in C++ deklariert
Code:
Aufruf:
typedef BOOL (*RESPONSE_FUNC)(UCHAR ucChannel, UCHAR ucResponseMsgID);
typedef BOOL (*CHANNEL_EVENT_FUNC)(UCHAR ucChannel, UCHAR ucEvent); typedef void (*P_ANT_ARF)(RESPONSE_FUNC, UCHAR*); typedef void (*P_ANT_AEF)(UCHAR, CHANNEL_EVENT_FUNC, UCHAR*);
Code:
Delphiübersetzung von mir
static BOOL Test_ChannelCallback(UCHAR ucChannel_, UCHAR ucEvent_);
static BOOL Test_ResponseCallback(UCHAR ucChannel_, UCHAR ucMessageId_); ANT_AssignResponseFunction(Test_ResponseCallback, aucResponseBuffer); ANT_AssignChannelEventFunction(USER_ANTCHANNEL,Test_ChannelCallback, aucChannelBuffer);
Code:
Aufruf:
function RESPONSE_FUNC(ucANTChannel: UCHAR; ucResponseMsgID: UCHAR): Boolean;
function CHANNEL_EVENT_FUNC(ucANTChannel: UCHAR; ucEvent: UCHAR): Boolean; TFNANT_AssignResponseFunction = procedure(RESPONSE_FUNC: Pointer; var pucResponseBuffer: Array of UCHAR); cdecl; TFNANT_AssignChannelEventFunction = procedure(ucANTChannel: UCHAR; CHANNEL_EVENT_FUNC: Pointer; var pucChannelBuffer: Array of UCHAR); cdecl;
Code:
Der Callback funktioniert, aber ucResponseMsgID und ucEvent ist immer 0.
ANT_AssignResponseFunction(@RESPONSE_FUNC, aucResponseBuffer);
ANT_AssignChannelEventFunction(USER_ANTCHANNEL, @CHANNEL_EVENT_FUNC, aucChannelBuffer); Muß ich noch was beachten ? Gruß Wal |
AW: Hilfe bei einem Callback einer C++ Dll nach Delphi
Müssten die beiden Callback-Funktionen nicht auch als cdecl deklariert werden?
|
AW: Hilfe bei einem Callback einer C++ Dll nach Delphi
Hat sich im Moment erledigt, habe die Dll mit VC++ 2010 Express neu erzeugt und es hat gefunzt.
Die Callback's sind wie oben zu sehen als cdecl deklariert. Die Funktionen sind ja Progammintern, die bei einem Callback angesprungen werden. Trotzdem Danke, brauche ja evtl. noch Hilfe, da ich noch nicht alles übersetzt habe. P.S. Das Ganze gehört zur Ant_Dll, mit dem man Ant+ Sensoren z.B. Garmin Pulsgurt, Trittfrequenzsensor über einen Ant+ USB-Stick z.B. Garmin USB Stick direkt in dem PC einlesen kann. |
AW: Hilfe bei einem Callback einer C++ Dll nach Delphi
Liste der Anhänge anzeigen (Anzahl: 1)
Leider zu früh gejubelt, war nur Zufall das die Werte in ucEvent und ucResponseMsgID gestimmt hatten.
Mit aucResponseBuffer und aucChannelBuffer kann ich arbeiten, da in diesen Arrays die richtigen Daten stehen und ich meine Herzfrequenz richtig auslesen kann. Habe die Source der Ant_Dll hochgeleden, wäre nett wenn jemand mal drüberschauen könnte. |
AW: Hilfe bei einem Callback einer C++ Dll nach Delphi
Zitat:
Das habe ich eben probiert, was soll ich sagen ... es geht. Warum muß ich die Funktion die nur Programmintern ist und auf die die Callbackprocedure verweist, auch mit cdecl deklarieren ?
Code:
unit ant_dll;
interface uses Windows, Forms, SysUtils, Dialogs; const USER_ANTCHANNEL = 0; USER_NETWORK_NUM = 0; // Indexes into message recieved from ANT MESSAGE_BUFFER_DATA1_INDEX = 0; MESSAGE_BUFFER_DATA2_INDEX = 1; MESSAGE_BUFFER_DATA3_INDEX = 2; MESSAGE_BUFFER_DATA4_INDEX = 3; MESSAGE_BUFFER_DATA5_INDEX = 4; MESSAGE_BUFFER_DATA6_INDEX = 5; MESSAGE_BUFFER_DATA7_INDEX = 6; MESSAGE_BUFFER_DATA8_INDEX = 7; MESSAGE_BUFFER_DATA9_INDEX = 8; MESSAGE_BUFFER_DATA10_INDEX = 9; MESSAGE_BUFFER_DATA11_INDEX = 10; MESSAGE_BUFFER_DATA12_INDEX = 11; MESSAGE_BUFFER_DATA13_INDEX = 12; MESSAGE_BUFFER_DATA14_INDEX = 13; type TMyArray1 = array[0..255] of AnsiChar; TMyArray2 = array[0..9] of Byte; TMyArray3 = array[0..16] of Byte; //////////////////////////////////////////////////////////////////////////////////////// // The following functions are used to manage the USB connection to the module //////////////////////////////////////////////////////////////////////////////////////// TFNANT_GetDeviceUSBInfo = function(ucUSBDeviceNum: UCHAR; var pucProductString: TMyArray1; var pucSerialString: TMyArray1): Boolean; cdecl; TFNANT_GetDeviceUSBPID = function(var pusPID: USHORT): Boolean; cdecl; TFNANT_GetDeviceUSBVID = function(var pusVID: USHORT): Boolean; cdecl; TFNANT_GetDeviceSerialNumber = function: ULONG; cdecl; TFNANT_Init = function(ucUSBDeviceNum: UCHAR; usBaudrate: USHORT): Boolean; cdecl; //Initializes and opens USB connection to the module TFNANT_Close = procedure; cdecl; //Closes the USB connection to the module TFNANT_LibVersion = function: AnsiChar; cdecl; TFNANT_AssignResponseFunction = procedure(RESPONSE_FUNC: Pointer; var pucResponseBuffer: TMyArray2); cdecl; TFNANT_AssignChannelEventFunction = procedure(ucANTChannel: UCHAR; CHANNEL_EVENT_FUNC: Pointer; var pucChannelBuffer: TMyArray3); cdecl; TFNANT_UnassignAllResponseFunctions = procedure; cdecl; //Unassigns all response functions //////////////////////////////////////////////////////////////////////////////////////// // Config Messages //////////////////////////////////////////////////////////////////////////////////////// TFNANT_UnAssignChannel = function(ucANTChannel: UCHAR): Boolean; cdecl; TFNANT_UnAssignChannel_RTO = function(ucANTChannel: UCHAR; ulResponseTime: ULONG): Boolean; cdecl; TFNANT_AssignChannel = function(ucANTChannel: UCHAR; ucChanType: UCHAR; ucNetNumber: UCHAR): Boolean; cdecl; TFNANT_AssignChannel_RTO = function(ucANTChannel: UCHAR; ucChanType: UCHAR; ucNetNumber: UCHAR; ulResponseTime: ULONG): Boolean; cdecl; TFNANT_AssignChannelExt = function(ucANTChannel: UCHAR; ucChanType: UCHAR; ucNetNumber: UCHAR; ucExtFlags: UCHAR): Boolean; cdecl; TFNANT_AssignChannelExt_RTO = function(ucANTChannel: UCHAR; ucChanType: UCHAR; ucNetNumber: UCHAR; ucExtFlags: UCHAR; ulResponseTime: ULONG): Boolean; cdecl; TFNANT_SetChannelId = function(ucANTChannel: UCHAR; usDeviceNumber: UShort; ucDeviceType: UCHAR; ucTransmissionType: UCHAR): Boolean; cdecl; TFNANT_SetChannelId_RTO = function(ucANTChannel: UCHAR; usDeviceNumber: UShort; ucDeviceType: UCHAR; ucTransmissionType: UCHAR; ulResponseTime: ULONG): Boolean; cdecl; TFNANT_SetChannelPeriod = function(ucANTChannel: UCHAR; usMesgPeriod: UShort): Boolean; cdecl; TFNANT_SetChannelPeriod_RTO = function(ucANTChannel: UCHAR; usMesgPeriod: UShort; ulResponseTime: ULONG): Boolean; cdecl; TFNANT_SetChannelSearchTimeout = function(ucANTChannel: UCHAR; ucSearchTimeout: UCHAR): Boolean; cdecl; TFNANT_SetChannelSearchTimeout_RTO = function(ucANTChannel: UCHAR; ucSearchTimeout: UCHAR; ulResponseTime: ULONG): Boolean; cdecl; TFNANT_SetChannelRFFreq = function(ucANTChannel: UCHAR; ucRFFreq: UCHAR): Boolean; cdecl; TFNANT_SetChannelRFFreq_RTO = function(ucANTChannel: UCHAR; ucRFFreq: UCHAR; ulResponseTime: ULONG): Boolean; cdecl; TFNANT_SetNetworkKey = function(ucNetNumber: Byte; pucKey: Array of UCHAR): Boolean; cdecl; TFNANT_SetNetworkKey_RTO = function(ucNetNumber: Byte; pucKey: Array of UCHAR; ulResponseTime: ULONG): Boolean; cdecl; TFNANT_SetTransmitPower = function(ucTransmitPower: UCHAR): Boolean; cdecl; TFNANT_SetTransmitPower_RTO = function(ucTransmitPower: UCHAR; ulResponseTime: UCHAR): Boolean; cdecl; //////////////////////////////////////////////////////////////////////////////////////// // ANT Control messages //////////////////////////////////////////////////////////////////////////////////////// TFNANT_ResetSystem = function: Boolean; cdecl; TFNANT_OpenChannel = function(ucANTChannel: UCHAR): Boolean; cdecl; TFNANT_OpenChannel_RTO = function(ucANTChannel: UCHAR; ulResponseTime: UCHAR): Boolean; cdecl; TFNANT_CloseChannel = function(ucANTChannel: UCHAR): Boolean; cdecl; TFNANT_CloseChannel_RTO = function(ucANTChannel: UCHAR; ulResponseTime: UCHAR): Boolean; cdecl; TFNANT_RequestMessage = function(ucANTChannel: UCHAR; ucMessageID: UCHAR):Boolean; cdecl; //////////////////////////////////////////////////////////////////////////////////////// // Threading //////////////////////////////////////////////////////////////////////////////////////// TFNANT_Nap = procedure(ulMilliseconds: ULONG); cdecl; function LoadAntDll: Boolean; function CloseAntDll: Boolean; function RESPONSE_FUNC(ucANTChannel: UCHAR; ucResponseMsgID: UChar): Boolean; cdecl; [SIZE="18"][COLOR="Red"]//<--Hier[/COLOR][/SIZE] function CHANNEL_EVENT_FUNC(ucANTChannel: UCHAR; ucEvent: UCHAR): Boolean; cdecl; [SIZE="18"][COLOR="Red"]//<--Hier[/COLOR][/SIZE] var ANT_GetDeviceUSBInfo : TFNANT_GetDeviceUSBInfo = Nil; ANT_GetDeviceUSBPID : TFNANT_GetDeviceUSBPID = Nil; ANT_GetDeviceUSBVID : TFNANT_GetDeviceUSBVID = Nil; ANT_GetDeviceSerialNumber : TFNANT_GetDeviceSerialNumber = Nil; ANT_Init : TFNANT_Init = nil; ANT_Close : TFNANT_Close = nil; ANT_LibVersion : TFNANT_LibVersion = Nil; ANT_AssignResponseFunction : TFNANT_AssignResponseFunction = Nil; ANT_AssignChannelEventFunction : TFNANT_AssignChannelEventFunction = Nil; ANT_UnassignAllResponseFunctions: TFNANT_UnassignAllResponseFunctions = Nil; ANT_ResetSystem : TFNANT_ResetSystem = Nil; ANT_SetNetworkKey : TFNANT_SetNetworkKey = Nil; ANT_AssignChannel : TFNANT_AssignChannel = Nil; ANT_SetChannelId : TFNANT_SetChannelId = Nil; ANT_SetChannelRFFreq : TFNANT_SetChannelRFFreq = Nil; ANT_SetChannelPeriod : TFNANT_SetChannelPeriod = Nil; ANT_OpenChannel : TFNANT_OpenChannel = Nil; ANT_CloseChannel : TFNANT_OpenChannel = Nil; ANT_RequestMessage : TFNANT_RequestMessage = Nil; ANT_Nap : TFNANT_Nap = Nil; AntLib: HMODULE; ucNetKey: Array[0..7] of Byte = ($B9, $A5, $21, $FB, $BD, $72, $C3, $45); usDevicePID : Word; usDeviceVID : Word; ucResponseBuffer: TMyArray2; ucChannelBuffer: TMyArray3; ucDeviceDescription: TMyArray1; ucDeviceSerial: TMyArray1; ucLibVersion: AnsiChar; implementation uses antdefines, antmessage, frmMain; function LoadAntDll: Boolean; begin result := False; AntLib := LoadLibrary(PChar('ANT_DLL.dll')); if AntLib <> 0 then begin @ANT_Init := GetProcAddress(AntLib, 'ANT_Init'); @ANT_Close := GetProcAddress(AntLib, 'ANT_Close'); @ANT_ResetSystem := GetProcAddress(AntLib, 'ANT_ResetSystem'); @ANT_Nap := GetProcAddress(AntLib, 'ANT_Nap'); @ANT_SetNetworkKey := GetProcAddress(AntLib, 'ANT_SetNetworkKey'); @ANT_GetDeviceUSBInfo := GetProcAddress(AntLib, 'ANT_GetDeviceUSBInfo'); @ANT_GetDeviceUSBVID := GetProcAddress(AntLib, 'ANT_GetDeviceUSBVID'); @ANT_GetDeviceUSBPID := GetProcAddress(AntLib, 'ANT_GetDeviceUSBPID'); //@ANT_GetDeviceSerialNumber := GetProcAddress(AntLib, 'ANT_GetDeviceSerialNumber'); @ANT_AssignChannel := GetProcAddress(AntLib, 'ANT_AssignChannel'); @ANT_SetChannelId := GetProcAddress(AntLib, 'ANT_SetChannelId'); @ANT_SetChannelRFFreq := GetProcAddress(AntLib, 'ANT_SetChannelRFFreq'); @ANT_SetChannelPeriod := GetProcAddress(AntLib, 'ANT_SetChannelPeriod'); @ANT_OpenChannel := GetProcAddress(AntLib, 'ANT_OpenChannel'); @ANT_CloseChannel := GetProcAddress(AntLib, 'ANT_CloseChannel'); @ANT_RequestMessage := GetProcAddress(AntLib, 'ANT_RequestMessage'); @ANT_AssignResponseFunction := GetProcAddress(AntLib, 'ANT_AssignResponseFunction'); @ANT_AssignChannelEventFunction := GetProcAddress(AntLib, 'ANT_AssignChannelEventFunction'); @ANT_LibVersion := GetProcAddress(AntLib, 'ANT_LibVersion'); result := True; if (@ANT_Init=nil) or (@ANT_Close=nil) or (@ANT_ResetSystem=nil) or (@ANT_Nap=nil) or (@ANT_SetNetworkKey=nil) or (@ANT_GetDeviceUSBInfo=nil) or (@ANT_GetDeviceUSBVID=nil) or (@ANT_GetDeviceUSBPID=nil) or //(@ANT_GetDeviceSerialNumber=nil) or (@ANT_AssignChannel=nil) or (@ANT_SetChannelId=nil) or (@ANT_SetChannelRFFreq=nil) or (@ANT_SetChannelPeriod=nil) or (@ANT_OpenChannel=nil) or (@ANT_CloseChannel=nil) or (@ANT_RequestMessage=nil) or (@ANT_AssignResponseFunction=nil) or (@ANT_AssignChannelEventFunction=nil) or (@ANT_LibVersion=nil) then Showmessage('Fehler!!!'); end else Showmessage('Fehler beim laden der Ant.dll'); end; function CloseAntDll: Boolean; begin if AntLib <> 0 then begin ANT_ResetSystem; ANT_Nap(1000); ANT_Close; FreeLibrary(AntLib); result := True; end else result := False; end; function RESPONSE_FUNC(ucANTChannel: UCHAR; ucResponseMsgID: UCHAR): Boolean; var i: Integer; str: String; begin outputdebugstring(Pchar(Inttohex(ucResponseMsgID, 1))); for I := 0 to 9 do str := str + ' ' + inttohex(ucResponseBuffer[i], 1); outputdebugstring(Pchar(str)); case ucResponseMsgID of MESG_RESPONSE_EVENT_ID: begin case ucResponseBuffer[MESSAGE_BUFFER_DATA3_INDEX] of RESPONSE_NO_ERROR: begin case ucResponseBuffer[MESSAGE_BUFFER_DATA2_INDEX] of MESG_ASSIGN_CHANNEL_ID: begin ANT_SetChannelId(0, 0, 120, 1); OutputDebugString('MESG_ASSIGN_CHANNEL_ID'); end; MESG_CHANNEL_MESG_PERIOD_ID: begin ANT_SetChannelRFFreq(0, 57); OutputDebugString('MESG_CHANNEL_MESG_PERIOD_ID'); end; MESG_NETWORK_KEY_ID: begin ANT_AssignChannel(0, 0, 0); OutputDebugString('MESG_NETWORK_KEY_ID'); end; MESG_CHANNEL_ID_ID: begin ANT_SetChannelPeriod(0, 8070);OutputDebugString('MESG_CHANNEL_ID_ID'); end; MESG_CHANNEL_RADIO_FREQ_ID: begin ANT_OpenChannel(0); OutputDebugString('MESG_CHANNEL_RADIO_FREQ_ID'); end; end; end; end; end; end; Result := True; end; function CHANNEL_EVENT_FUNC(ucANTChannel: UCHAR; ucEvent: UCHAR): Boolean; var i: Integer; str: String; begin outputdebugstring(Pchar(Inttohex(ucEvent, 1))); for I := 0 to 16 do str := str + ' ' + inttohex(ucChannelBuffer[i], 1); outputdebugstring(Pchar(str)); str := IntToStr(ucChannelBuffer[8]); if str <> Form1.lab_Puls.Caption then Form1.lab_Puls.Caption := str; Result := True; end; end. Gruß Wal |
AW: Hilfe bei einem Callback einer C++ Dll nach Delphi
Weil der Callback von der DLL aufgerufen wird und dieser in c++ dann eben die Parameter als cdecl uebergibt und Delphi denkt es waere Register? Ich würd ja generell für alle prcoedure stdcall verwenden sowohl in Delphi als auch in c++ wenn du die dll sowieso erstellst.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz