2016-12-22 5 views
3

해당 주소로 C++ DLL에서 C 함수를 호출하려고합니다.반환 형식을 모른 채 해당 주소로 C++에서 함수를 호출합니다.

반환 유형이이 별도 질문에서 알 수있는 곳에서 수행하는 방법을 알고 있습니다 : Calling a function through its address in memory in c/c++.

그러나 반환 유형을 모르면 무엇을 할 수 있습니까? "typedef auto"를 시도했지만 자동 검색 기능을 사용할 수없는 것 같습니다.

+3

반환 유형을 모르는 경우 어떻게 될 것으로 예상됩니까? 함수를 호출해야하는 방식 (호출 규칙)은 반환 유형에 따라 다릅니다. – jtbandes

+6

나쁜 소식은 컴파일 타임에 반환 유형을 모르는 경우 수작업으로 작성한 어셈블리 언어가 없으면 * 불가능하다는 것입니다. 좋은 소식은 누군가가 이미 어셈블리 언어를 직접 작성했다고 가정합니다. [libffi] (https://sourceware.org/libffi/). – zwol

+0

런타임에 반환 유형을 알고 있습니까? –

답변

2

반환 유형이 실제로 알 수 없거나 중요하지 않은 경우 함수 정의에 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 함수가 집계를 반환 할 때 더욱 그렇습니다.

+0

반환 형식이 큰 집계이면 호출 규칙이 변경됩니다. –