Also hier mal der C++Source um das Python-Modul und die funktion zu laden:
Code: Alles auswählen
void func(std::string _module, char* _arg ...) {
	std::vector<std::string> py_args;
	std::vector<std::string> arguments;
	std::string bak_dir = "";
	va_list ap; // will point to each unnamed argument in turn
	int num;
	double d;
	std::string s;
	char* ss;
	const char *p=_arg;
	va_start(ap, _arg); // point to first element after _arg
	while(*p) {
		switch(*p) {
			case 'i': // int
				num=va_arg(ap,int);
				py_args.push_back(NodeConfigFunctions::LongToStr(num));
				//printf("%d",num);
				break;
			case 'd': //double
				d=va_arg(ap,double);
				py_args.push_back(NodeConfigFunctions::LongToStr(d));
				//printf("%f",d);
				break;
			case 's': // char*
				ss=va_arg(ap,char*);
				s = ss;
				py_args.push_back(s);
				//printf("%s",s.c_str());
				break;
			case 'S': // std::string
				s=va_arg(ap,std::string);
				py_args.push_back(s);
				//printf("%s",s.c_str());
				break;
			default:
				printf("unsupported format flag");
		}
		++p;
	}
	va_end(ap); //cleanup
	try {
		if(py_args.empty())
			throw FileError("Cannot find any functions");
		std::string py_module_name = _module;
		std::string py_function = py_args[0];
		py_args.erase(py_args.begin());
		PyObject *pName, *pModule, *pDict, *pFunc;
		PyObject *pArgs, *pValue, *pValueRepr;
		pName = PyString_FromString(py_module_name.c_str());
		/* Error checking of pName left out */
		// Change the module directory and remember the current directory
		if(!this->directory.empty()) {
			bak_dir = _getcwd(NULL, 0);
			_chdir(this->directory.c_str());
		}
	
		// Import python module
		pModule = PyImport_Import(pName);
		// Change to the previous directory
		if(!this->directory.empty())
			_chdir(bak_dir.c_str());
		if (pModule != NULL) {					        
			// pFunc is a new reference
			pFunc = PyObject_GetAttrString(pModule, py_function.c_str());
			if (pFunc && PyCallable_Check(pFunc)) {
				pArgs = PyTuple_New(py_args.size());
				for (int i = 0; i < py_args.size(); ++i) {
					//pValue = PyInt_FromLong(atoi(py_arguments[i].c_str()));
					pValue = PyString_FromString(py_args[i].c_str());
					if (!pValue) {
						//Py_DECREF(pArgs);
						//Py_DECREF(pModule);
					   /* fprintf(stderr, "Cannot convert argument\n");
						return 1;*/
						char buffer[2048] = {0};
						sprintf(buffer, "Cannot convert argument\n");
						throw FileError(buffer);
					}
					/* pValue reference stolen here: */
					PyTuple_SetItem(pArgs, i, pValue);
				}
				pValue = PyObject_CallObject(pFunc, pArgs);
				pValueRepr = PyObject_Repr(pValue);
				//Py_DECREF(pArgs);
				if (pValue != NULL) {
					std::string value = PyString_AsString(pValueRepr);
					trim(value, '\"');
					printf("%s\n", value.c_str());
					//Py_DECREF(pValue);
				}
				else {
					//Py_DECREF(pFunc);
					//Py_DECREF(pModule);
					PyErr_Print();
					/*fprintf(stderr,"Call failed\n");
					_sleep(5000);
					return 1;*/
					char buffer[2048] = {0};
					sprintf(buffer, "Call failed\n");
					throw FileError(buffer);
				}
			}
			else {
				if (PyErr_Occurred()) {
					PyErr_Print();
					//_sleep(5000);
				}
				/*
				fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
				_sleep(5000);*/
				char buffer[2048] = {0};
				sprintf(buffer, "Cannot find function \"%s\"\n", py_function.c_str());
				throw FileError(buffer);
			}
		}
		else {
			PyErr_Print();
			char buffer[2048] = {0};
			sprintf(buffer, "Failed to load \"%s\"\n", py_module_name.c_str());
			throw FileError(buffer);
			/*fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
			_sleep(5000);
			return 1;*/
		}
		Py_Finalize();
	}
	catch(FileError &e) {
		cerr << e.what() << endl;
	}
}
Was möchte ich machen?
ich will von C++ aus Python scripts ausführen und deren return values in C++ weiterverarbeiten. Mit Statischen typen funktioniert und ist mehr oder weniger ein kinderspiel. Mir geht es um dynamisches Datentypen die mir vorher nicht bekannt sind.
Beispiel was funktioniert (sehr "simple" beispiel):
TypA (von C++) = string oder int, ...
TypB (VonPython)  = string oder int, ...
1.) C++ (TypA) => übergabe an Python(TypB)
2.) Result von Python(TypB) => übergabe an C++ (TypA)
3.) weiterverwendung von TypA...
aufruf unter c++:
testmodul.py:
So in diesem Beispiel wären mir also unter C++ folgende Funktionen bekannt:
C++ => Python	...	PyString_ToString
Python => C++	...	PyString_AsString
Für int, float usw. gibts equivalente Funktionen
Jetzt hat aber ein Programmierer ein Python script hinzugefügt, welches einen Int zurückliefert.
Nun habe ich dann ein Problem, weil PyString_AsString nicht funktioniert, stattdessen müsste ich die Funktion PyInt_AsString verwenden. 
Nur vorher weiß ich was für einen Typ ich zurückbekomme?
bzw. wie weiß ich was für einen Typ ich übergebe?
Beispiel:
Code: Alles auswählen
def myFunc(arg):
    if(arg == "test1"):
        return 1
    elif(arg == "test2"):
        return 2
    else:
        return 0
Hier müsste ich PyString_ToString und von Python nach C++ zurück PyInt_AsInt verwenden, nur woher weiß ich das.
Kann man irgendwie ermitteln welchen Typ das PyObject hat und dieses dann dementsprechend casten?
Und/Oder kann man ermitteln welche typen eine funktion benötigt?
Lg NoRulez[/code]