einbinden vom c und c++

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.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Wahrscheinlich hast du vorher einfach nur ein "import ctypes" vergessen.
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Du musst die Module auch erstmal importieren, damit sie bekannt sind.

Also zuerst:

Code: Alles auswählen

import math
und dann

Code: Alles auswählen

dir(irgendwas)


ne0h
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Warum bin ich immer zu langsam... :?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

sechsrad hat geschrieben:bei dir(ctypes) kommt "NameError: name 'ctypes' is not defined"
Man muss ``ctypes`` vorher importieren, bevor man es mit ``dir`` analysieren kann.

EDIT:
ne0h hat geschrieben:Warum bin ich immer zu langsam... :?
Und du glaubst, du bist langsam? ;-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Masaru hat geschrieben:So wie du das da versuchst sechsrad, funktioniert es bei mir auch nicht ...
Eine andere, meines Erachtens einfachere Variante, da die C-Funktionen nicht umständlich angepasst werden müssen, wäre mit restype:

Code: Alles auswählen

import ctypes

f = ctypes.cdll.LoadLibrary('test.dll')
f.mult.restype = ctypes.c_float
print f.mult(ctypes.c_float(34.3))
print 3.7 * 34.3
Hierbei kann dann sechsrads Original-DLL

Code: Alles auswählen

#include <math.h>

float mult(float n) {
float a;
a = n * 3.7;
return a;
}
verwendet werden.
MfG
HWK
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

da kommt dieses als ergebnis : -1.#IND

mfg
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

die variante von masaru funktioniert jetzt :

Code: Alles auswählen

#!/usr/bin/env python

from ctypes import *
f =cdll.LoadLibrary("test.dll")

ff=pointer(c_float())
tt=pointer(c_char_p())

b=c_float(10.0)
f.mult(b,ff)
print ff.contents.value

b=c_float(10.8)
f.div(b,ff)
print ff.contents.value

f.text(tt)
print tt.contents.value
und die dll:

Code: Alles auswählen

#include <math.h>

void mult(float n, float* r) {
*r=n*3.7;
} 

void div(float n, float* r) {
*r=n/2.0;
}

void text(int* r) {
char text[] = "hurra, es geht !\n";
*r=text;
}

ergebnis ist dieses hier :
D:/Python25/pythonw.exe -u "D:/Python25/test-py/dll/dll1.py"
37.0
5.40000009537
hurra, es geht !
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

sechsrad hat geschrieben:

Code: Alles auswählen

void text(int* r) {
char text[] = "hurra, es geht !\n";
*r=text;
}
Aua. Ich hoffe mal, dass nur dein Testcode so aussieht.
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

aua, es ging nur darum, wie man text aus einer dll übertragen kann, aua.

das andere ergibt dann die feinarbeit. die funktion steht jetzt erstmal im vordergrund.

wie man dieses char jetzt ausfüllt, da gibt es ja verschiedene möglichkeiten in c.

eine textfunktion aus einer dll hatte ich hier im ganzen forum noch nicht gefunden.

es funktioniert erst einmal, das ist wichtig.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

sechsrad hat geschrieben: eine textfunktion aus einer dll hatte ich hier im ganzen forum noch nicht gefunden.
Warum auch....das hier ist kein C-Forum.

du hast übrigens noch immer nicht diese unglaublich komplexen Rechnungen gezeigt, die in Python zu langsam sind.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

sechsrad hat geschrieben:es funktioniert erst einmal, das ist wichtig.
Nur damit das klargestellt ist: es ist reiner Zufall, dass die text-Funktion funktioniert.
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

nochmals danke für die hilfe mit einer dll in python einbinden.

mein ziel ist erreicht, klappt wunderbar mit allen was ich mir vorgestellt habe.

danke.

mfg

Nur damit das klargestellt ist: es ist reiner Zufall, dass die text-Funktion funktioniert.
ich meine, eine zeigerübergabe ist kein zufall, ich glaube(gehe auch in die kirche) das ist die einfachste lösung.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

sechsrad hat geschrieben:ich meine, eine zeigerübergabe ist kein zufall, ich glaube(gehe auch in die kirche) das ist die einfachste lösung.
Das stimmt, das Übergebens eines Zeigers ist kein Zufall. Jedoch befindet sich der String auf dem Stack und damit ist nach Abarbeitung der Funktion auch der Inhalt auf den der Zeiger zeigt undefiniert.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

sechsrad hat geschrieben:da kommt dieses als ergebnis : -1.#IND

mfg
Ich weiß ja nicht, was Du da gemacht hast, bei mir kommt jedenfalls folgendes heraus:

Code: Alles auswählen

C:\Programme\Python24\Scripts\Test>type test.py
#!/usr/bin/env python

import ctypes

f = ctypes.cdll.LoadLibrary('test.dll')
f.mult.restype = ctypes.c_float
print f.mult(ctypes.c_float(34.3))
print 3.7 * 34.3

C:\Programme\Python24\Scripts\Test>test.py
126.909996033
126.91
MfG
HWK
BlackJack

@EyDu: Die Zeichenkette sollte sich nicht auf dem Stack befinden. Das würde ja bedeuten, dass die Zeichenkette bei jedem Aufruf von woanders dort hin kopiert werden müsste, und da literale Zeichenketten "read only" sind, wäre das ziemlich unsinnig.

Aber die Funktion ist trotzdem total falsch. Erstens ist das Rückgabeargument vom Typ ``int*`` und dann wird nicht die Zeichenkette zurückgegeben, sondern die Adresse als Zahl. Wenn man den Rückgabeargumenttyp auf ``char*`` korrigieren würde, ist es immer noch nicht richtig, da dann versucht würde einen Zeiger in ein Zeichen zu konvertieren.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Und meine Variante:
Python-Script

Code: Alles auswählen

#!/usr/bin/env python

import ctypes

f = ctypes.cdll.LoadLibrary('test.dll')
f.mult.restype = ctypes.c_float
f.div.restype = ctypes.c_float
f.text.restype = ctypes.c_char_p
print f.mult(ctypes.c_float(10))
print f.div(ctypes.c_float(10.8))
print f.text()
DLL

Code: Alles auswählen

#include <math.h>

char TEXT[] = "Das ist ein Test\n";

float mult(float n) {
    return 3.7 * n;
}

float div(float n) {
    return n / 2;
}

char* text() {
    return TEXT;
}
Ausgabe

Code: Alles auswählen

>C:\Programme\Python24\pythonw -u "test.py"
37.0
5.40000009537
Das ist ein Test

>Exit code: 0
MfG
HWK
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

BlackJack hat geschrieben:@EyDu: Die Zeichenkette sollte sich nicht auf dem Stack befinden. Das würde ja bedeuten, dass die Zeichenkette bei jedem Aufruf von woanders dort hin kopiert werden müsste, und da literale Zeichenketten "read only" sind, wäre das ziemlich unsinnig.
Das mag ja durchaus sein, dass eine Compiler in diesem Fall optimiert, aber im allgemeinen Fall kann man nicht davon ausgehen:

Code: Alles auswählen

void text(int* r) { 
char text[] = "hurra, es geht !\n";
text[4] = **a random character**;
*r=text; 
}
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

übergabestring, erweiterung,rückgabe

python-code:

Code: Alles auswählen

   
#!/usr/bin/env python

from ctypes import *
f =cdll.LoadLibrary("test.dll")

tt=pointer(c_char_p())
text=c_char_p("dies ist ein text")

f.text_out_in(text,tt)
print tt.contents.value
---------------------------------------------
print-ausgabe:

dies ist ein text ,es geht !
----------------------------------------------

dll:

Code: Alles auswählen

void text_out_in(char* text, int* r){
    char neustr[12]=" ,es geht!\0";
    strcat (text,neustr);
    *r=text;
}
[/code]
Zuletzt geändert von sechsrad am Donnerstag 10. April 2008, 07:50, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Jetzt schreibst du irgendwo in der Gegend rum. Du musst schon einen String übergeben, der ausreichend Platz für das Ergebnis hat.

Und du bist dir wirklich sicher, dass du deine Programme mit C "optimieren" willst?
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

EyDu hat geschrieben:
BlackJack hat geschrieben:@EyDu: Die Zeichenkette sollte sich nicht auf dem Stack befinden. Das würde ja bedeuten, dass die Zeichenkette bei jedem Aufruf von woanders dort hin kopiert werden müsste, und da literale Zeichenketten "read only" sind, wäre das ziemlich unsinnig.
Das mag ja durchaus sein, dass eine Compiler in diesem Fall optimiert, aber im allgemeinen Fall kann man nicht davon ausgehen:

Code: Alles auswählen

void text(int* r) { 
char text[] = "hurra, es geht !\n";
text[4] = **a random character**;
*r=text; 
}
BlackJack hat schon recht, wie man hier am Assemblercode von

Code: Alles auswählen

char* text() {
    char TEXT[] = "Das ist ein Test\n";
    return TEXT;
}
in Mingw sieht:

Code: Alles auswählen

6ABC11AC  ASCII "Das ist ein Test\n",0
6ABC11BE  PUSH EBP
6ABC11BF  MOV EBP,ESP
6ABC11C1  SUB ESP,28
6ABC11C4  MOV EAX,DWORD PTR DS:[6ABC11AC]
6ABC11C9  MOV DWORD PTR SS:[EBP-28],EAX
6ABC11CC  MOV EAX,DWORD PTR DS:[6ABC11B0]
6ABC11D1  MOV DWORD PTR SS:[EBP-24],EAX
6ABC11D4  MOV EAX,DWORD PTR DS:[6ABC11B4]
6ABC11D9  MOV DWORD PTR SS:[EBP-20],EAX
6ABC11DC  MOV EAX,DWORD PTR DS:[6ABC11B8]
6ABC11E1  MOV DWORD PTR SS:[EBP-1C],EAX
6ABC11E4  MOV AX,WORD PTR DS:[6ABC11BC]
6ABC11EA  MOV WORD PTR SS:[EBP-18],AX
6ABC11EE  LEA EAX,DWORD PTR SS:[EBP-28]
6ABC11F1  LEAVE
6ABC11F2  RETN
Das ist meines Erachtens gängiges Verhalten von C-Compilern. D.h. der Code wird aus dem Code-Segment immer in einen evtl. unterschiedlichen Bereich des Stacks kopiert. Probleme gibt es v.a. dann, wenn neue Funktionen aufgerufen werden. Diese können nämlich diesen Stackbereich überschreiben. Nicht umsonst warnt deshalb der C-Compiler, dass hier die Adresse einer lokalen Variable übergeben wird.
MfG
HWK
Antworten