2012-06-21 4 views
0

나는 시도하고이 DLL에있는 함수를 찾기 위해 DLL 내보내기 뷰어를 사용하고, 나는 기능의 목록을 발견하고 여기있다 : 문제는 C#에서 내DLL에서이 함수를 원래 호출하는 방법은 무엇입니까?

public: int __thiscall CSTVdsDisk::GetPartitionCount(void); 

내가 할 수 없습니다입니다

[DllImport("Some.dll", 
      ExactSpelling = true, 
      EntryPoint = "GetPartitionCount", 
      CallingConvention = CallingConvention.StdCall, 
      SetLastError = true)] 

나 :

[DllImport("Some.dll", 
      ExactSpelling = true, 
      EntryPoint = "CSTVdsDisk::GetPartitionCount", 
      CallingConvention = CallingConvention.StdCall, 
      SetLastError = true)] 
private static extern int GetPartitionSize(); 

그들은 모두 실패 중 하나를 사용하여 함수를 호출합니다. 내가 잘못하고있는 것이 있습니까? 누구든지 도와 줄 수 있습니까? 감사!

+0

이것을 시도해 볼 수 있습니까? [DllImport ("Some.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int GetPartitionSize(); –

+0

지금 찾을 수없는 오류가 발생했습니다. –

답변

2

P/Invoke를 사용하여 해당 기능을 호출 할 수 없습니다. __thiscall 호출 참조는이 함수가 클래스 멤버 함수임을 의미합니다. CSTVdsDisk 클래스의 멤버 함수입니다.

함수를 호출하려면 CSTVdsDisk 클래스의 인스턴스를 만들고 해당 인스턴스에서 GetPartitionCount을 호출해야합니다.

C++에서 C++ 클래스를 만들 수 없으므로 C++ 또는 C++/CLR에서이 작업을 수행해야합니다. Create unmanaged c++ object in c#을 참조하십시오.

+0

Windows에서는 PE 함수 내보내기로 C++ 생성자를 노출 할 수 있습니다. C++ 외부에서 사용하는 것은 완전히 엉망입니다. –

0

네이티브 코드에서 함수를 내보내고 있는지 확인하십시오. 기본적으로 함수는 내보내기 테이블에 나열되지 않으므로 컴파일러가이를 내보낼 수 있도록 표시해야합니다. 컴파일러가 이름을 변경하지 않도록 함수를 extern "C" 으로 표시해야합니다.

#define DLLEXPORT extern "C" __declspec(dllexport) 

는이 모든 것을 처리하고 단순히 같은 수출 함수를 선언하는 :

일반적으로 나는 다음과 같은 매크로를 정의

DLLEXPORT __cdecl int Example(int x, int y) 

당신은 여전히에 문제가 발생하는 찾을 경우 이름에 dll에있는 무료 PE 탐색기 프로그램을 사용하고 내 보낸 함수 테이블에서 올바른 이름을 확인하십시오.

+0

DLL에 대한 소스가 없기 때문에 다른 프로그램의 함수를 사용하려고합니다. C에서 디스크를 포맷 할 수 있습니다. # –

+0

그런 경우 PE 익스플로러를 사용하여 올바른 내 보낸 이름을 가져 오는 방법에 대한 설명으로 건너 뜁니다. 30 일 동안 "PE Explorer"의 평가판 http://www.heaventools.com/overview.htm을 사용할 수 있습니다.이 기능은 편리합니다. –

1

이름을 기반으로하면 C++ 클래스 방법 인 것 같습니다. 즉, 매우 어려운 두 가지 이유 호출/P에서 직접 메소드를 호출 할 수 있도록하는 것입니다 : 당신은 "진짜"이름을 찾을 필요가

  1. ; 익스포트 뷰어 (Export Viewer)는 분명히 얽혀 있지 않은 이름을 보여주고 있지만, 실제로는 C++ 함수 이름이 @[email protected]@@QPBAEXA 또는 그와 비슷한 훨씬 더 못 생깁니다. 해당 이름을 찾으려면 dumpbin과 같은 하위 수준 도구를 사용해야 할 수도 있습니다.
  2. "thiscall"스타일 호출을 위조해야합니다. 즉, C++ 클래스의 인스턴스를 첫 번째 매개 변수로 전달해야 함을 의미합니다. 이것은 C++ 클래스 생성자가 DLL에서도 노출되어있는 경우에만 작동합니다. 이 경우 클래스 생성자를 호출하고 결과를 IntPtr에 저장 한 후 모든 후속 호출에 전달할 수 있습니다. 생성자는 DLL의 수출로 노출 된 경우 (그 변환 된 이름은

This CodeProject article 당신이 어떻게의 대부분을 보여줍니다`?? 0CSTVdsDisk @@ QAE @ ABV0 @@ Z처럼 ??로 시작하지만, 그것은 꽤입니다 깨지기 쉽기 때문에 문제를 기대하십시오.나는 강력하게 non-C++ 라이브러리를 찾거나 비슷한 것을하거나 적어도 하나는 C 코드에서 사용할 수 있도록 설계된 라이브러리를 찾길 추천한다.

관련 문제