2014-10-14 15 views
-1

C++에서 DLL을 동적으로로드해야합니다.C++ GetProcAddress()에서 정적 클래스의 메서드를 찾을 수 없습니다.

나는이 튜토리얼 http://msdn.microsoft.com/en-us/library/ms235636.aspx을 따라 dll을 만들고 모든 것이 잘 동작했다.

그럼 나는이 일 http://msdn.microsoft.com/en-us/library/64tkc9y5.aspx을 따라 나는 다음과 같이 콘솔 응용 프로그램을 채택했습니다

typedef DOUBLE(CALLBACK* DllFunc)(DOUBLE, DOUBLE); 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HINSTANCE hDLL;    // Handle to DLL 
    DllFunc dllFunc1; 
    DOUBLE p1 = 1.0, p2 = 2.0, r; 
    hDLL = LoadLibrary(L"MathFuncsDLL"); 
    if (hDLL != NULL) 
    { 
     cout << "DLL loaded: " << hDLL << endl; 
     dllFunc1 = (DllFunc)GetProcAddress(hDLL, "[email protected]@Multiply"); 
     if (!dllFunc1) 
     { 
      // handle the error 
      FreeLibrary(hDLL); 
      cout << "Function not found!" << endl; 
      return -1; 
     } 
     else 
     { 
      // call the function 
      r = dllFunc1(p1, p2); 
      cout << "The result is: " << r << endl; 
     }    
    } 
    else { 
     cout << "Dll not found" << endl; 
     return -1; 
    } 
    cout << "Press any key to exit." << endl; 
    int i; 
    cin >> i; 
    return 0; 
} 

DLL이 제대로 넣었는지, 그것이 null이 아닙니다. 문제는 항상 0을 반환하는 GetProcAddress() 함수입니다.

모든 네임 스페이스, 클래스 이름, 메서드 이름 조합을 시도했습니다. 함수 이름에 @ 대신 범위 연산자 (: :)를 사용하려고했습니다.

전체 네임 스페이스를 extern "C" 으로 정의하려고했지만 아무 것도 변경되지 않았습니다. 콘솔 응용 프로그램을 실행하거나 디버깅 할 때마다 '곱하기'기능을 찾을 수 없습니다.

내가 뭔가를 놓치고 있다고 생각합니다 ... 어디에서 잘못 되었나요? 하지 왜 ...

DLL Export table

가 지금은 함수 이름의 마지막 부분이 무엇을 의미하는지 궁금 을 :


편집

종속성 워커는 나에게 다음과 같은 내보내기 테이블을 노출 __declspec (dllexports)는 이러한 기호를 추가합니까?

+0

이 DLL의 기호를 덤프하고 추가하십시오 :

이 인터페이스 클래스를 선언하는 적절한 방법입니다. – Deduplicator

+1

그 이름을 어디에서 얻었는지 짐작하기는 쉽지 않습니다. MSVC++ 컴파일러의 경우 "? Multiply @ MyMathFuncs @ MathFuncs @@ SANNN @ Z"가되어야합니다. DLL에서 Dumpbin.exe/exports를 사용하여 이름을 확인하십시오. DLL 프로젝트가 생성 한 .lib 파일을 링크하여 이런 일을하지 않아도됩니다. –

+0

질문을 내보내기 이름이 표시된 스크린 샷으로 업데이트했습니다. 틀림없이 우리는 끝났습니다. 너는 무엇을 더 기대하고 있니? –

답변

2

내 보낸 함수 이름을 검사하려면 dumpbin 또는 Dependency Viewer와 같은 도구를 사용하십시오. 이것은 당신이 당신의 사건에 적용 가능성이 고장 모드의 어떤 진단 할 수 있습니다 :이 기능은 내보낼 수 없습니다

  1. , 또는 기능이 수출되고
  2. ,하지만 이름은 장식 또는
  3. 기능 예상 한 이름으로 내보내지만 잘못 입력 한 것입니다.
3

C++ 이름 맹 글링에 오신 것을 환영합니다. 컴파일러가 함수 이름에 추가하는 모든 걸림쇠는 고유 한 서명이있는 각 함수가 고유 한 이름을 갖도록 보장하는 것입니다. 마이크로 소프트는 한 방법으로 mangling의 이름을 짓고 GCC/Clang은 다른 것을 그렇게합니다. 표준화되지는 않았지만 특정 OS의 컴파일러는 모두 동일한 방식으로 맹 글링 (mangling)하여 모든 것을 처리 할 수 ​​있습니다.

사용자가 이름을 예측할 수있는 유일한 방법은 내 보낸 DLL 함수를 extern "C"으로 선언하는 것입니다. 그러나 이것은 C 함수를 내보내는 것을 제한합니다.

내가 작업 한 라이브러리에는 라이브러리를 초기화하고 인터페이스 포인터를 가져 오는 내 보낸 C 함수가 하나 있습니다. 이 경우 "인터페이스"는 데이터가없고 가상 기능 만있는 추상 가상 기본 클래스를 의미합니다.

struct my_interface 
{ 
    virtual int my_function1(int param1, int param2) = 0; 
    virtual int my_function2(const char *param) = 0; 

#if CHOOSE_DESTRUCTION_TYPE 

protected: 
    // Protected non-virtual destructor prevents the use of delete on the interface pointer. 
    // Must be defined because it will be used as objects of derived types are destructed. 
    ~my_interface() {}; 

#else 

    // Public virtual destructor allows the use of delete on the interface pointer. 
    virtual ~my_interface() = 0; 

#endif 

private: 
    // Private copy assignment prevents "*ptr1 = *ptr2". 
    // This odd syntax CAN be supported, but you probably shouldn't. 
    // Only needs to be declared because nobody can call it. 
    my_interface & operator=(const my_interface &); 

    // Ditto for move assignment. 
    my_interface & operator=(my_interface &&); 
};