wrapper dll
-
Hallo,
vorab: ich bin ein absoluter anfänger in c++ und ich hoffe die frage ist nicht zu blöd.
ich versuche eine dll in labview zu integrieren die einen zeiger auf eine callback funktion benötigt (geht in labview nicht). ich muss also eine wrapperdll schreiben die mit loadlibary und getrpocadress sozusagen den zeiger erzeug.
mit stürzt beim aufrufen der dll leider labview komplett ab: mein code:
// wrapperfuerant.cpp : Definiert die exportierten Funktionen für die DLL-Anwendung.
//
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>typedef unsigned long int (*ANT_vFn)();
__declspec( dllexport ) unsigned long int (ANT_vFN);
ANT_vFn ANT_AssignChannelEventFunction = NULL;
void DLLint()
{
HINSTANCE hDLL = NULL;
hDLL = LoadLibrary("ANT_DLL.dll");if(hDLL == NULL)
return;else {
ANT_AssignChannelEventFunction = (ANT_vFn)GetProcAddress(hDLL, "_ANT_AssignChannelEventFunction");if(ANT_AssignChannelEventFunction == NULL){
FreeLibrary(hDLL);
return;
}
}
}hat vielleicht jemand eine ahnung wieso das passiert? oder kann mir wer helfen zu lernen wie das funktionieren könnte? (würde auch dafür zahlen)
lg
sojahulk
-
codetagging made easy by sothis
#include "stdafx.h" #include <stdio.h> #include <windows.h> typedef unsigned long int (*ANT_vFn)(); __declspec( dllexport ) unsigned long int (ANT_vFN); ANT_vFn ANT_AssignChannelEventFunction = NULL; void DLLint() { HINSTANCE hDLL = NULL; hDLL = LoadLibrary("ANT_DLL.dll"); if (hDLL == NULL) return; else { ANT_AssignChannelEventFunction = (ANT_vFn)GetProcAddress(hDLL, "_ANT_AssignChannelEventFunction"); if (ANT_AssignChannelEventFunction == NULL) { FreeLibrary(hDLL); return; } } }bist du dir auch sicher, dass GetProcAdress einen gültigen Zeiger zurückliefert? ich würde die von labview benötigte funktion direkt implementieren und aus dieser funktion die eigentliche funktion "ANT_AssignChannelEventFunction" aufrufen (dann natürlich mit einem anderen bezeichner). dann hast du etwas flexibelere möglichkeiten zur fehlerbehandlung

-
hallo - vorab mal: danke für die antwort

wenn ich das richtig verstanden habe lade ich die dll,
rufe dann die funktio in der dll auf
BOOL ANT_ChannelEventFunction(UCHAR ucChannel, UCHAR ucEvent); UCHAR aucChannelEventBuffer[MESG_DATA_SIZE]; ANT_AssignChannelEventFunction(channel_0, &ANT_ChannelEventFunction, aucChannelEventBuffer);(laut der doku)
inludiere alle header files die auch die usprüngliche dll hat (wegen der ganzen definitionen usw.)
und lasse mir dan also das ergebnis von "ANT_AssignChannelEventFuncion" zurückgeben? würde das so gehen?
danke vielmals

sojahulk
-
Ich würde eiene separate DLL machen, die dir ermöglicht eine DLL in LabView zu Laden, z.B. so:
HINSTANCE h = 0; int myLoadLibrary(const char* lib) { if(h == 0) { h = LoadLibrary(lib); return 0; // ok } return 1; // error } void myFreeLibrary() { FreeLibrary(h); } // übergib addr in LabView der anderen DLL-Funktion int myGetProcAddress(const char* proc, int* addr) { if(h != 0) { *addr = (int)GetProcAddress(h, proc); return *addr != 0; // ok } return 1; // error }Die Funktionsadresse kannst du dann in Labview der anderen DLL als Integer übergeben.
-
Hallo nochmals,
vorab - danke für die antwort

ich habs jetzt mal probiert aber irgendwie hauts nicht hin.
folgender code:
##include "stdafx.h" #include <windows.h> HINSTANCE h = 0; const char* lib ="MeineDLL.dll"; const char* proc="DLL Funktion"; extern "C" __declspec(dllexport) int myDLLload(LPCWSTR lib) { if(h == 0) { LPCWSTR lib = libinput; h = LoadLibrary(lib); return 0; // ok } return 1; // error } // übergib addr in LabView der anderen DLL-Funktion extern "C" __declspec(dllexport) int myDLLgetprocaddr(LPCSTR proc, int* addr) { if(h != 0) { *addr = (int)GetProcAddress(h, proc); return *addr != 0; // ok } return 1; // error } extern "C" __declspec(dllexport) void myDLLFree() { FreeLibrary(h); }ich habe dann probiert, in labview die dll aufzurufen - hat auch funktioniert nur gibt sie mir nix zurück...

Die funtkion myDLLload gibt mir irgendwie immer 0 zurück, egal wie ich lib defineire... und myDLLgetprocaddress funktionier nicht (returnwert 1; address 0).
ich bin für jede hilfe und antwort sehr sehr sehr dankbar.
lg
hulk
-
Sicher nur ein Problem des Pfades, bzw. des Arbeitsverzeichnisses.
Guck mal mit GetLastError()...
Simon
-
Für mehr Flexibilität könntest du auch den Pfad und den Funktionsnamen aus Labview der DLL übergeben. Dann musst du nicht immer neu Kompilieren, wenn du eine andere Library laden willst:
#include <windows.h> HINSTANCE h = 0; // weg damit! // const char* lib ="MeineDLL.dll"; // const char* proc="DLL Funktion"; // die call library node konfigurerst du so: // int32 myDLLload(const char* lib) // lib ist ein Labview-String, den du als const char* übergibst! extern "C" __declspec(dllexport) int myDLLload(const char* lib) { if(h == 0) { h = LoadLibrary(lib); return 0; // ok } return 1; // error } // auch hier übergibst du füp proc einen LV-String als char*! // addr übergibst du als pointer auf int32 extern "C" __declspec(dllexport) int myDLLgetprocaddr(const char* proc, int* addr) { if(h != 0) { *addr = (int)GetProcAddress(h, proc); return *addr == 0; // ok } return 1; // error } extern "C" __declspec(dllexport) void myDLLFree() { FreeLibrary(h); h = 0; }
-
Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
hallo leute,
soda - dank eurer hilfe habe ich es nun geschafft einen pointer auf eine dllfuction zu bekommen (die ich mit dem labview appbuilder gemacht habe) und sie an meine zieldll als zeiger auf einen wert zu übergeben. das hätte, laut labviewforen funktionieren sollen. wie das leben so ist funktionierts nicht :p
da hab ich mir dann gedanken gemacht und ein wenig im internet geguckt und hätte folgende frage.
ist es möglich einen zeiger auf die addresse von der callbackfunktion der dll selbst zu bekommen? schaut folgendermaßen aus(in der .c datei)
typedef struct { CHANNEL_EVENT_FUNC pfLinkEvent; UCHAR *pucRxBuffer; } CHANNEL_LINK;und wird von
__declspec (dllexport) void ANT_AssignChannelEventFunction(UCHAR ucLink, CHANNEL_EVENT_FUNC pfLinkEvent, UCHAR *pucRxBuffer) { sLink[ucLink].pfLinkEvent = pfLinkEvent; sLink[ucLink].pucRxBuffer = pucRxBuffer; }benötigt.
in der .h ist es wie folgt definiert
// Application callback function pointer typedef BOOL (*CHANNEL_EVENT_FUNC)(UCHAR ucANTChannel, UCHAR ucEvent);und wird von
void ANT_AssignChannelEventFunction(UCHAR ucANTChannel, // Initialize Channel pointers CHANNEL_EVENT_FUNC pfChannelEvent, UCHAR *pucRxBuffer);benötigt.
danke im voraus für die hilfe

martin
-
hallo,
vorab mal danke fürs helfen.. aber ich komm jetzt überhautp nimmer weiter...

ich möchte ja eigentlich nix anderes tun, als die daten die im *pucRxBuffer stehen auslesen.
ich habe es versucht wie in der dokumentation zu machen (http://www.thisisant.com/index.php?module=resourcesmodule&src=@random43c2ebc53db95) aber ich bring das einfach nicht zusammen.
vorgestellt hätte ich es mir so, dass ich die assignchanneleventfunction aus der herstellerdll lade, sie mit der callbackfunktion versorge und mir den zeiger auf den pucRxBuffer zurückgeben lasse.
-- soweit so gut -- aber wie schaut die callbackfunktion denn nun aus?
danke im voraus für alle tipps
hulk
-
Hallo,
sojahulk__ schrieb:
-- soweit so gut -- aber wie schaut die callbackfunktion denn nun aus?
Man erkennt aus diesem hier:
typedef BOOL (*CHANNEL_EVENT_FUNC)(UCHAR ucANTChannel, UCHAR ucEvent);dass die Callback-Funktion so:
BOOL myChannelEventFunction(UCHAR ucANTChannel, UCHAR ucEvent) { // Code }aussehen muss, aber das willst du wahrscheinlich auch nicht wissen, weil du das oben schon erkannt hast:
BOOL ANT_ChannelEventFunction(UCHAR ucChannel, UCHAR ucEvent);
UCHAR aucChannelEventBuffer[MESG_DATA_SIZE];
ANT_AssignChannelEventFunction(channel_0, &ANT_ChannelEventFunction, aucChannelEventBuffer);MfG,
Probe-Nutzer
-
hallo,
danke für die antwort.
bleibt eigentlich nur noch eine frage offen.
hab folgendes geschreiben:
/* * Dynastream Innovations Inc. * Cochrane, AB, CANADA * * Copyright © 1998-2007 Dynastream Innovations Inc. * All rights reserved. This software may not be reproduced by * any means without express written approval of Dynastream * Innovations Inc. */ /* * VCS Information - autogenerated - do not modify * * ************************************************************************** * * ************************************************************************** */ #include "stdafx.h" #include "types.h" #include "antdefines.h" #include "antmessage.h" #include "callbackwrapper.h" ////////////////////////////////////////////////////////////////////////////////// // Public Variables ////////////////////////////////////////////////////////////////////////////////// // Function Pointers P_ANT_ARF ANT_AssignResponseFunction; P_ANT_AEF ANT_AssignChannelEventFunction; ////////////////////////////////////////////////////////////////////////////////// // Private Variables ////////////////////////////////////////////////////////////////////////////////// static UCHAR aucChannelEventBuffer[10]; static HMODULE hANTdll; static BOOL bLoaded = FALSE; UCHAR ucChannel; ////////////////////////////////////////////////////////////////////////////////// // Public Functions ////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// extern "C" __declspec(dllexport) BOOL ANT_Load(void) { if (bLoaded) return TRUE; hANTdll = LoadLibraryA("ANT_DLL.dll"); if (hANTdll == NULL) return FALSE; ANT_AssignResponseFunction = (P_ANT_ARF) GetProcAddress(hANTdll, "ANT_AssignResponseFunction"); ANT_AssignChannelEventFunction = (P_ANT_AEF) GetProcAddress(hANTdll, "ANT_AssignChannelEventFunction"); if (ANT_AssignResponseFunction == NULL) return FALSE; if (ANT_AssignChannelEventFunction == NULL) return FALSE; bLoaded = TRUE; return TRUE; } /////////////////////////////////////////////////////////////////////// extern "C" __declspec(dllexport) void ANT_UnLoad(void) { if (hANTdll != NULL) { FreeLibrary(hANTdll); } bLoaded = FALSE; } /////////////////////////////////////////////////////////////////////// BOOL __cdecl ANT_ChannelEventFunction(UCHAR ucChannel, UCHAR ucEvent) { if(aucChannelEventBuffer != 0){ aucChannelEventBuffer[MESG_DATA_SIZE]; return(TRUE); } else{ return(FALSE); } } extern "C" __declspec(dllexport)UCHAR* ANT_EVENT(UCHAR ucChannel) { ANT_AssignChannelEventFunction(ucChannel, &ANT_ChannelEventFunction, aucChannelEventBuffer); return aucChannelEventBuffer; }leider bekomme ich in labview (zumindest keinen absturz mehr hin
)den inhalt vom aucChannelEventBuffer zurück. soweit ich das verstanden habe besteht der buffer aus einem array - muss ich da vielleicht die werte irgendwie rauslesen?danke
martin