LabVIEWForum.de
Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+---- Forum: DLL & externer Code (/Forum-DLL-externer-Code)
+---- Thema: Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" (/Thread-Fatal-Error-LabVIEW-LIB-could-not-locate-PostLVUserEven)

Seiten: 1 2 3


Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - abrissbirne - 18.09.2009 09:56

Der Titel sagt eigentlich schon alles. Ich habe ehrlich gesagt keine Ahnung wieso dieser Error auftritt, da ich schon 100te male mit den LabVIEW.LIB Funktionen gearbeitet habe. Ich habe die richtige Version in meinem Projekt gelinkt (siehe Srceenshots) der Code lässt sich auch ohne Warnung compilieren, aber beim Ablauf kommt es zu diesem crash. Der einzige Unterschied zu meinen Vorgängerprojekten liegt darin, dass mein Quellcode abstrakte Klassen beinhaltet. Dieses dürfte aber eigentlich nicht der Grund sein.


Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - IchSelbst - 18.09.2009 10:23

' schrieb:Der einzige Unterschied zu meinen Vorgängerprojekten liegt darin, dass mein Quellcode abstrakte Klassen beinhaltet. Dieses dürfte aber eigentlich nicht der Grund sein.
Würde ich aber schon sagen (gerade bei LV respektive LVOOP).

Die Meldung klingt sehr nach Laufzeitfehler. Daher geht es ja zu kompilieren. Es fehlt ihm wohl eine zur Laufzeit notwendige Instanzierung einer abstrakten Methode (ich vermute für PostLVUserEvent muss eine "reale" Methode her).


Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - abrissbirne - 18.09.2009 11:48

' schrieb:Würde ich aber schon sagen (gerade bei LV respektive LVOOP).

Die Meldung klingt sehr nach Laufzeitfehler. Daher geht es ja zu kompilieren. Es fehlt ihm wohl eine zur Laufzeit notwendige Instanzierung einer abstrakten Methode (ich vermute für PostLVUserEvent muss eine "reale" Methode her).
Ich verwende kein LVOOP. Das sind alles C++ Objekte. Dann dürften doch aber Funktionen wie NumericArrayResize()... auch nicht funktionieren, oder? Das tun sie aber. Alle Funktionen außer PostLVUserEvent.


Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - rolfk - 18.09.2009 11:53

PostLVUserEvent() ist eine C Manager Funktion in LabVIEW. LabVIEW.LIB ist so gemacht dass es alle manager Funktionen dynamisch linkt, d.h erst wenn sie zum ersten Mal aufgerufen werden. Dazu stellt es das aufrufende LabVIEW Module fest - LabVIEW.exe (oder lvrt.dll für eine Applikation) - und macht dann ein GetProcAddress für die entsprechende Funktion. Da der Fehler von LabVIEW.LIB kommt muss es von einer C Routine kommen, also eine DLL die irgendwo in Deinem Code eingebunden wird.

PostLVUserEvent() ist eine ziemlich advanced Funktion also entweder rufst Du eine NI DLL irgendwo auf oder Du hast Dir irgendwo eine entsprechende DLL hergeholt. Kann es sein dass Du versuchst eine DLL die eigentlich für LabVIEW gedacht ist in einem nicht LabVIEW Kontext auszuführen (beispieslweise einem Executable dass dann über Remoting, Out of Process ActiveX oder was auch immer) irgendwie in LabVIEW integriert wird)?

Oder Deine abstrakten Klassen machen das LabVIEW Environment so spezial dass LabVIEW.lib in Deiner DLL die LabVIEW Runtime nicht mehr lokalisieren kann.

Rolf Kalbermatter


Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - abrissbirne - 18.09.2009 13:09

' schrieb:PostLVUserEvent() ist eine C Manager Funktion in LabVIEW. LabVIEW.LIB ist so gemacht dass es alle manager Funktionen dynamisch linkt, d.h erst wenn sie zum ersten Mal aufgerufen werden. Dazu stellt es das aufrufende LabVIEW Module fest - LabVIEW.exe (oder lvrt.dll für eine Applikation) - und macht dann ein GetProcAddress für die entsprechende Funktion. Da der Fehler von LabVIEW.LIB kommt muss es von einer C Routine kommen, also eine DLL die irgendwo in Deinem Code eingebunden wird.

PostLVUserEvent() ist eine ziemlich advanced Funktion also entweder rufst Du eine NI DLL irgendwo auf oder Du hast Dir irgendwo eine entsprechende DLL hergeholt. Kann es sein dass Du versuchst eine DLL die eigentlich für LabVIEW gedacht ist in einem nicht LabVIEW Kontext auszuführen (beispieslweise einem Executable dass dann über Remoting, Out of Process ActiveX oder was auch immer) irgendwie in LabVIEW integriert wird)?

Oder Deine abstrakten Klassen machen das LabVIEW Environment so spezial dass LabVIEW.lib in Deiner DLL die LabVIEW Runtime nicht mehr lokalisieren kann.

Rolf Kalbermatter
Also die einzige DLL die ich dynamisch lade ist eine von einem Kamerahersteller. Also keine NI DLL. Mein Code ist eigentlich gar nichtmal so kompliziert. Ich mache mal ein vereinfachtes Bsp.:
Abstrakte Klasse:
<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>class cam_interface
{
public:
Abstract_Cam_Interface();
virtual ~Abstract_Cam_Interface();
virtual int Connect()= 0;
}
</div>
Kamaeraklasse:
<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>class Kamera : public virtual cam_interface
{
private:
Cam_DLL_Fcts FctAddr; // Struktur für die Einsprungadressen.
public:
// Auf Konstruktor und Destruktor habe ich fürs Forum verzichtet.
int Connect();
}</div>
Zugehörige CPP:
<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>int Kamera::Connect()
{
HINSTLIB Lib = LoadLibrary("cam.dll")
if(Lib)
{

Kamera::FctAddr.GetSources = (irb_GetSources)GetProcAddress(Lib, "cam_GetSources");
Kamera::FctAddr.InitSource = (irb_InitSource)GetProcAddress(Lib, "cam_InitSource");
Kamera::FctAddr.CloseSource = (irb_CloseSource)GetProcAddress(Lib, "cam_CloseSource");
Kamera::FctAddr.Grab = (irb_Grab)GetProcAddress(Lib, "cam_Grab");
}

this->GetFctAddr().GetSources(&SrcID); // Adresse auf Variable welche mit der SourceID beschrieben wird.
this->InitSource(SrcID); // Verbindungsaufbau mit der Quelle.
this->Grab(void* buf); // buf wurde vorher mit new allociert.
TD1Hdl LVMem = NULL; // Struktur wurde vorher angelegt.
NumericArrayResize(uW, 1L, SizeX*SizeY); // SizeX SizeY entspricht der Kameraauflösung.
(*LVMem)->DimSize = SizeX*SizeY;
MoveBlock(buf, &LVMem.Elements, sizeof(unsigned short int) * SizeX * SizeY)
PostLVUserEvent(Ref, &LVMem); // Ref wurde vorher von LV Übergeben.

return this->CloseSource(SrcID);
}
}
</div>
DLL Main:
<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>
extern "C" __declspec(dllexport) int Connect()
{
Kamera Cam; // Objekt der Klasse erzeugen.
Abstract_Cam_Interface *Interface = &Cam; // Interfacepointer anlegen.
return Interface->Connect(); // Funktion ausführen.
}
</div>


Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - rolfk - 18.09.2009 13:17

Du gehst da viel zu weit. Warum linkst Du denn die LabVIEW.lib in Dein VS Projekt? Da wirst Du wohl irgendwo LabVIEW manager Funktionen aufrufen, oder? Und irgendwie ist da auch PostLVUserEvent() irgendwie darunter!

Ich denke mal nicht dass die 3rd Party DLL LabVIEW Funktionen versucht aufzurufen. Oder hat die Unterstützung für LabVIEW Events????

Rolf Kalbermatter


Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - abrissbirne - 18.09.2009 13:30

' schrieb:Du gehst da viel zu weit.
Warum?
' schrieb:Warum linkst Du denn die LabVIEW.lib in Dein VS Projekt?
Ich muss die doch linken wg. der LabVIEW.lib
' schrieb:Da wirst Du wohl irgendwo LabVIEW manager Funktionen aufrufen, oder?
Jo siehe oben NumericArrayResize()
' schrieb:Und irgendwie ist da auch PostLVUserEvent() irgendwie darunter!
Siehe oben in der zugehörigen CPP
' schrieb:Ich denke mal nicht dass die 3rd Party DLL LabVIEW Funktionen versucht aufzurufen. Oder hat die Unterstützung für LabVIEW Events????

Rolf Kalbermatter
Nein hat sie nicht. Das mache alles ich.


Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - rolfk - 18.09.2009 14:02

Also C++ ist leider nicht meine Stärke.

Was da eine abstrakte Klasse alles reinhauen kann ist mir völlig unklar. Aber Du wirst Dich mal mit Deinem Code befassen müssen der PostLVUserEvent() aufruft, weil NumericArrayResize() alleine wirst Du sicher nicht verwenden. Und dann musst Du Dir mal sehr genau überlegen in welchem Context die entsprechende Funktion aufgerufen wird.

Das MUSS im selben Context sein, in dem Du von LabVIEW aus die Initialisierung Deiner DLL aufrufst. Das kann ganz sicher nicht in einem externen Thread sein. Vielleicht gibts Du ja dem Camera-Treiber eine Callback Routine in der Du die PostLVUserEvent() Funktion aufrufst aber der Treiber versucht diese Callback Routine in einem anderen Prozess Context auszuführen. Wie das direkt auf DLL Niveau gehen könnte ist mir nicht klar, aber wenn .Net Remoting, ActiveX Marshalling und weiss ich noch was für ekelige Dinge in dem Treiber bemüht werden, könnte das schon irgendwie geschehen.

Rolf Kalbermatter


Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - abrissbirne - 18.09.2009 14:20

' schrieb:Das kann ganz sicher nicht in einem externen Thread sein.
Was meinst du mit externem Thread? Ich hatte einmal eine "normale" Klassenarchitektur (abstrakte klasse und davon abgeleitete sind auch nichts anderes, nur anders organisiert) in denen ich die Datenaufnahme in einen Thread ausgelagert hatte und das funktionierte wunderbar.


Fatal Error:LabVIEW.LIB could not locate "PostLVUserEven" - rolfk - 18.09.2009 14:56

' schrieb:Was meinst du mit externem Thread? Ich hatte einmal eine "normale" Klassenarchitektur (abstrakte klasse und davon abgeleitete sind auch nichts anderes, nur anders organisiert) in denen ich die Datenaufnahme in einen Thread ausgelagert hatte und das funktionierte wunderbar.

Ein Thread der von einem Out Of Process Server gestarted wurde. Da das ein anderer Prozess ist als Deine LabVIEW Applikation, hat der auch keinerlei Idee von einer lvrt.dll und selbst wenn er die fände wäre das sinnlos, da Userevent Refnums nur in dem LabVIEW Context Sinn machen der sie auch erzeugt hat (und mit Context meine ich hier nicht nur den LabVIEW Prozess sondern die Application Referenz, wobei beispielswiese ein VI aus einem Project aufgestartet eine andere Applikation Referenz hat als ein anderes VI das global oder aus einem anderen Projekt heraus gestartet wurde).

Diese letzte Information ist allerdings zu Deiner Fehlermeldung irrelevant da Du in dem Fall von PostLVUserEvent einen error 1, manager Argument Error oder ähnlich zurückerhalten würdest, weil die Userevent Refnum ungültig ist. Aber soweit kommts bei Dir nicht mal, da die entsprechende Funktion die PostLVUserEvent aufruft in einem anderen Prozess aufgerufen zu werden scheint dann Deiner LabVIEW Applikation.

Ich tippe noch immer auf eine Callbackfunktion die Du an Deinen Treiber gibts und die dieser aus einem anderen Prozess oder was auch immer auszuführen versucht. Wahrscheinlich ist da sowas wie ActiveX Marshalling involviert und der Treiber erwartet dass Deine Callbackfunktion von einem anderen Prozess aus ausgeführt werden kann und selber das Marshalling der entsprechenden Daten in Deinen Zielprozess (hier LabVIEW) durchführt. Wenn dem so wäre hast Du eine "schöne" Aufgabe vor Dir.

Ersetzen der PostLVUserEvent() Funktion durch Windows Events wäre dann wohl eine der besseren Lösungen. Das könntest Du innerhalb des LabVIEW Prozess dann wieder durch einen eigenen Thread in PostLVUserEvents() umsetzen.

Rolf Kalbermatter