Python verbunden mit DLL - Funktion wird nicht gefunden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Abend,

Ich bin dabei zum Ersten Mal (für mich^^) eine DLL Datei in Python aufzurufen.
Nach etwas belesen fand ich immer das ähnliche Muster:

Code: Alles auswählen

import ctypes 

def script_to_cm(file):
    return dll.LoadGpc(file)
    
dll = ctypes.windll.LoadLibrary('LibCronusMAX.dll')
script_to_cm("Fortnite_Personal_Script.gpc")
aber es gibt immer nur aus, dass die Funktion "LoadGpc(<filename>)" nicht gefunden wurde:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\Philipp\Desktop\Eigene_Programme\API's\CronusMax_API\Send_GPC_Test.py", line 7, in <module>
    script_to_cm("Fortnite_Personal_Script.gpc")
  File "C:\Users\Philipp\Desktop\Eigene_Programme\API's\CronusMax_API\Send_GPC_Test.py", line 4, in script_to_cm
    return dll.LoadGpc(file)
  File "C:\Users\Philipp\AppData\Local\Programs\Python\Python35\lib\ctypes\__init__.py", line 360, in __getattr__
    func = self.__getitem__(name)
  File "C:\Users\Philipp\AppData\Local\Programs\Python\Python35\lib\ctypes\__init__.py", line 365, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'LoadGpc' not found
Verwendete API:
public void LoadGpc(string filename); - Same as above, except it takes a filename and will load whatever is in the file as bytecode
Ich finde auch nichts hilfreiches im Internet und da ich noch nie mit einer DLL Datei (also Python mit C++) gearbeitet habe, weiß ich auch nicht wo der Fehler liegen könnte.
Schätze Mal, dass ich die Funktion auch falsch aufrufe?
Vllt eine Idee wo de Fehler liegt und vllt irgendeine Quelle wo ich mich belesen kann, wie ich das machen muss?

Grüße,
xXSkyWalkerXx1
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

DLLs exportieren Funktionen, damit sie gefunden werden. Und diese DLL scheint nicht diese Funktion zu exportieren.
Woher hast Du den Aufruf?

Falls Du den selbst geraten hast: Du weißt, dass C/C++ name mangling benutzen.
Zweitens: wenn die Funktion wirklich etwas vom Typ "string" erwartet: Du mußt selbst dafür sorgen, dass die Argumente auch von diesem Typ (der kein Python-Typ noch etwas, was ctypes kennt) ist.
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich vermute bei der Signatur handelt es sich weder um C noch um C++, sondern um C#, und die kannst du nicht mit Python aufrufen. Da wirst du zu einer mehrprozess-Lösung greifen müssen, mit einem C# (oder IronPython, wenn’s das noch gibt) Program, das per IPC mit deinem Python Programm kommuniziert.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Es gibt https://pythonnet.github.io/ um von CPython aus auf .NET-Assemblies zuzugreifen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

@Sirius
Dafür hab ich ja extra den Aufruf der API mit erwähnt. Da steht drin, dass die Funktion "LoadGpc" heißt.

@__deets__
Sicher? Denn ich habe in der API Datei auch Beispiel Codes gesehen, die in C++ geschrieben wurden - aber ich kann später, wenn ich Heme bin, nochmals nachschauen, vllt irre ich mich auch. Obwohl, die Importierung in diesen Codes war mit "using...", das ist ja C# - oder?

@_blackjack__
Okay, danke - schaue später Mal rein, wenn ich wieder Heme bin.
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es ist garantiert kein C++. Und WENN es C++ wäre, würde dir ctypes nix nutzen.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Und woran erkenne ich, dass es kein C++ ist bzw. worin hast du es erkannt?
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Kannst ja mal deine Syntax in einen C++ Compiler gießen & gucken ob der das schluckt. Genauso wenig wie er Python schluckt. Ist halt C#.
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mir war doch so.... das ist übrigens alles kalter Kaffee: das haben wir schon vor langer Zeit alles diskutiert. viewtopic.php?t=43159&start=15
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

__deets__ hat geschrieben: Donnerstag 23. Mai 2019, 20:53 Mir war doch so.... das ist übrigens alles kalter Kaffee: das haben wir schon vor langer Zeit alles diskutiert. viewtopic.php?t=43159&start=15
Hehe, stimmt. ^^ habe garnicht an den Thread gedacht.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

__blackjack__ hat geschrieben: Mittwoch 22. Mai 2019, 17:02 Es gibt https://pythonnet.github.io/ um von CPython aus auf .NET-Assemblies zuzugreifen.
Hab's Mal mit PythonNet versucht, aber dann fand ich heraus, dass es nicht mit NET 4.0+ nicht kompatibel ist. :D
Gibt es da Alternativen?
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wie hast Du das herausgefunden? Denn der erste Satz auf der Website des Projekts sagt das es für .NET 4.0+ ist: „Python for .NET (pythonnet) is a package that gives Python programmers nearly seamless integration with the .NET 4.0+ Common Language Runtime (CLR) […]“
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

__blackjack__ hat geschrieben: Samstag 18. April 2020, 14:32 Wie hast Du das herausgefunden? Denn der erste Satz auf der Website des Projekts sagt das es für .NET 4.0+ ist: „Python for .NET (pythonnet) is a package that gives Python programmers nearly seamless integration with the .NET 4.0+ Common Language Runtime (CLR) […]“
https://stackoverflow.com/questions/132 ... mbly-error

Ja guuut...die Seite, die du nahmst, also die offizielle Homepage, hatte ich auch schon. Hätte ich vllt mal ein paar Zeilen mehr lesen sollen. ^^

Code: Alles auswählen

import clr,sys
sys.path.append("C:\\Users\\Philipp\\Desktop\\Python\\ModMenu - Consoles\\")
clr.AddReference("LibCronusMAX")

from LibCronusMAX import UnloadGpc
UnloadGpc()
Nun bekomme ich den Fehler, dass es "UnloadGpc" nicht importieren kann.

Die API-Dok. sagt:
public void UnloadGpc(); - A function you can call to unload the current GPC script from memory, NOTE: this function cannot be used while in API mode
Muss, denke ich zumindest, an einem Kompatibilitätsproblem liegen.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@xXSkyWalkerXx1: Die Doku sollte auch verraten in welcher Klasse diese Methode definiert ist. Und eventuell hast Du da ein ``static`` in der Signatur vergessen? Falls nicht, müsstest Du auch tatsächlich erst einmal ein Exemplar erstellen.

@all: Oder kann man in .NET tatsächlich Funktionen in DLLs/Assemblies haben?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Also...Ja,klar, man brauch erstmal eine Klasse, die auch in der API zu finden war. :D

Aber irgendwie zweifle ich daran, ob die API was bewirkt, also, ob sie wirklich etwas macht.
(Hier der Code...)

Code: Alles auswählen

import clr,sys,os
path = os.path.dirname(os.path.abspath(__file__))
script = path + "\\CronusMax_Version"
sys.path.append(path)
clr.AddReference("LibCronusMAX")

from LibCronusMAX import SingleDevice, DeviceInformation
#Part 1 (Load Script)
device = SingleDevice()
device.StartWorkerThreads()#to communicate with CronusMax device
device.LoadGpc(script)
#Part 2 (Get Bool: IsHubCompatible)
settings = DeviceInformation()
IsHubCompatile = settings.IsHubCompatible
print(IsHubCompatile)
Im Part 1, wenn der ausgeführt wird, passiert nichts mit meinem CronusMax - keine LED Änderung, nichts...
Im Part 2 bekomme ich in der Zeile einen Error ("TypeError: no constructor matches given arguments"), in der "settings" definiert wird (nicht beim Import, der klappt).
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Also das Problem liegt wohl nur in der "DeviceInformation" Klasse, alle anderen funktionieren.
Habe gelesen, dass beim genannten Fehler wohl das binden scheitert.
Antworten