반환 유형이 실제로 알 수 없거나 중요하지 않은 경우 함수 정의에 void
을 사용할 수 있습니다. 또는 포인터가 있으면 void *
을 사용할 수 있지만 함수가 C 코딩 된 DLL에있는 경우 C++ 코드에서 사용하면 C++에서 C의 상위 집합이므로 C 코드에 정의 된 거의 모든 유형을 활용하고 공유 할 수 있습니다.
즉, PyObject
이라는 구조로 된 작은 예제를 준비했습니다. C 및 C++ 코드로 공유됩니다.
더 잘 공유 유형/정의와 헤더 생성되고, 이렇게하려면 다음을 수행
#ifndef PYOBJECT_DLL_H
#define PYOBJECT_DLL_H
#ifdef __cplusplus
extern "C" {
#endif
// Common structure definition
typedef struct PyObject{
int field1;
char *field2;
} PyObject;
// Public function pointer type declaration
typedef PyObject *(*__stdcall getPyObject_t)(int arg1, const char *arg2);
#ifdef __cplusplus
}
#endif
#endif // PYOBJECT_DLL_H
이의 내 보낸 기능을 가진 C 코드가 있다고 가정하자 뭔가 같은 :
#include "pyobject.h"
#include <stdlib.h>
#ifdef __cplusplus
extern "C"
#endif
__declspec(dllexport) PyObject * getPyObject(int arg1, char *arg2);
PyObject *getPyObject(int arg1, char *arg2){
PyObject *obj = (PyObject *)malloc(sizeof(PyObject));
obj->field1 = arg1;
obj->field2 = arg2;
return obj;
}
마지막으로 라이브러리에서 작성된 함수 및 데이터를 사용하는 C++ 코드는 다음과 같습니다.
0
@raymondchen으로
#include "pyobject.h"
#include <iostream>
#include <windows.h>
int main() {
HINSTANCE dll = LoadLibrary("pyobject.dll");
if (dll == NULL) {
std::cerr << "Cannot open pyobject.dll. Error: " << GetLastError() << "\n";
return 1;
}
getPyObject_t getPyObject = (getPyObject_t) GetProcAddress(dll, "getPyObject");
if (getPyObject == NULL) {
std::cerr << "Cannot locate 'getPyObject' function in dll. Error: " << GetLastError() << "\n";
FreeLibrary(dll);
return 2;
}
PyObject *obj = getPyObject(3, "test");
std::cout << "PyObject == { field1: " << obj->field1 << ", field2: \"" << obj->field2 << "\"}\n";
FreeLibrary(dll);
return 0;
}
편집
는 C 함수가 큰 집계를 반환 할 때 반환 형식을 무시하고, 자신의 의견에 지적 (예를 들어, struct) C 함수는 호출자가 반환 된 집계를 저장하기 위해 스택 공간을 이미 예약 했으므로 호출자가 함수를 void
또는 다른 것으로 처리하는 경우 컴파일러가 해당 공간을 예약하지 않기 때문에 좋은 생각이 아닙니다. 예측할 수없는 영향 (Segmentation 오류로 끝날 가능성이 높음)
이를 방지하려면 C 및 C++ 코드 (또는 공용 헤더)에서 올바른 형식을 정의하는 것이 좋습니다. 특히 C 함수가 집계를 반환 할 때 더욱 그렇습니다.
반환 유형을 모르는 경우 어떻게 될 것으로 예상됩니까? 함수를 호출해야하는 방식 (호출 규칙)은 반환 유형에 따라 다릅니다. – jtbandes
나쁜 소식은 컴파일 타임에 반환 유형을 모르는 경우 수작업으로 작성한 어셈블리 언어가 없으면 * 불가능하다는 것입니다. 좋은 소식은 누군가가 이미 어셈블리 언어를 직접 작성했다고 가정합니다. [libffi] (https://sourceware.org/libffi/). – zwol
런타임에 반환 유형을 알고 있습니까? –