2010-11-25 2 views
0

다음 코드는 C#에서 호출 할 때 작동하지만 관리되는 영역에서 데이터 을 가져 와서 로컬 원시 복사본을 만들고 Win32 함수를 호출 한 다음 데이터를 다시 관리되는 매개 변수로 복사하기 때문에 비효율적 인 것으로 보입니다. 호출자에게 반환됩니다.C++/CLI 추적 핸들을 Win32 용 네이티브 포인터로 변환 하시겠습니까?

다음을 수행하는 방법이 있습니까?

1) blittable UInt32 참조 매개 변수를 Win32 호출에 직접 전달 하시겠습니까? 이 Win32 호출이 호출자 (예 : theSerialNumber)에게 반환 할 값을 업데이트한다는 사실을 유의하십시오. UION32 참조 매개 변수 (예 : theSerialNumber)를native 함수가 사용하고 직접 값을 업데이트 할 수있는 LPDWORD로 pin_ptr 연결할 수 있습니까? ?

2) StringBuilder 버퍼를 네이티브 함수에 직접 전달 하시겠습니까? 나는 StringBuilder.Capacity = MAX_PATH + 1을 설정할 필요가 있다고 상상한다. 하지만, 어떻게 내 기본 버퍼를 사용하고 업데이 트 자사의 내부 버퍼에 pin_ptr 수 있습니다.

나는 몇 시간 동안이 질문에 대한 내 머리를 실험하고 검색하고 두드렸다. 그래서 나는 당신의 헬프에 정말 감사 할 것입니다!

감사합니다,

마이크


당신은 문자열 유형 (관리 문자열과 기본 WCHAR *) 모두 있기 때문에 마샬링의 두 가지를 제거 할 수
void MCVolume::VolumeInformation(String^ theRootPathName, 
      StringBuilder^% theVolumeName, 
      UInt32% theSerialNumber, 
      UInt32% theMaxComponentLength, 
      MEFileSystemFeature% theFileFlags, 
      StringBuilder^% theFileSystemName) 
{ 

pin_ptr<const wchar_t> rootPathName = PtrToStringChars(theRootPathName); 

wchar_t volumeName[MAX_PATH+1]; 
memset(volumeName, 0x0, MAX_PATH+1); 
wchar_t fileSystemName[MAX_PATH+1]; 
memset(fileSystemName, 0x0, MAX_PATH+1); 
DWORD serialNumber = 0; 
DWORD fileFlags = 0; 
DWORD maxComponentLength = 0; 

//pin_ptr<DWORD> serialNumber = &theSerialNumber; 

if (GetVolumeInformationW(rootPathName, 
      volumeName, 
      MAX_PATH+1, 
      &serialNumber, 
      &maxComponentLength, 
      &fileFlags, 
      fileSystemName, 
      MAX_PATH+1) == false)         
{ 
    // Handle error 
    throw gcnew Exception("GetVolumeInformationW failed."); 
} 

// Send back results... 
theVolumeName = gcnew StringBuilder(marshal_as<String^>(volumeName)); 
theSerialNumber = serialNumber; 
theMaxComponentLength = maxComponentLength; 
theFileFlags = (MEFileSystemFeature) fileFlags; 
theFileSystemName = gcnew StringBuilder(marshal_as<String^>(fileSystemName)); 

답변

0

는 근본적으로 다르다. 또한 GC는 할당 된 관리 리소스를 추적해야하므로 관리되는 세계로 다시 보내지는 객체는 항상 System::String^으로 만들어야합니다.

+0

사실이 아닙니다. * 관리되는 세계로 되돌려 보낼 개체를 만들 필요가 없습니다. P/Invoke를 사용하여 컴파일러가 작업을 수행하도록하십시오. –

+0

@ taspeotis : 예를 보여 줄 수 있습니까? 이것은 나를 위해 다소 새로운 것입니다. – Aamir

+0

@Aamir - 안녕하세요, [이 링크] (http://weblogs.asp.net/kennykerr/archive/2005/06/20/414010.aspx)에서는 P/Invoke를 사용하려는 예제와 상황을 보여줍니다. C + +/CLI 대 마샬링 자신을 관리하는 (말장난 없음). –

0

C++/CLI의 P/Invoke를 사용하십시오. 자세한 내용은 here을 참조하십시오.

관련 문제