C ++ / CLI Преобразовать дескриптор отслеживания в родной указатель для Win32? - PullRequest
0 голосов
/ 25 ноября 2010

Следующий код работает при вызове из C #, но он кажется неэффективным, потому что я беру данные из управляемого мира, делаю их локальные собственные копии, вызываю функцию Win32, а затем копирую данные обратно в управляемые параметры, которыевозвращается к вызывающей стороне.

Есть ли способ выполнить следующее?

1) Передать параметры blittable UInt32 напрямую в вызов Win32?Обратите внимание, что этот вызов Win32 обновляет значения, которые я хочу вернуть вызывающей стороне (т. Е. TheSerialNumber). В сущности, я могу pin_ptr ссылочный параметр UInt32 (т. Е. TheSerialNumber) как LPDWORD, который может использовать нативная функция, и напрямую обновлять его значение?1005 *

2) Передать буферы StringBuilder непосредственно в нативную функцию?Я полагаю, что мне нужно было бы установить StringBuilder.Capacity = MAX_PATH + 1;Но я понятия не имею, как закрепить pin_ptr во внутреннем буфере, который будет использовать и обновлять нативная функция.

Я часами экспериментировал, искал и стучал по этим вопросам, поэтому я действительноценим вашу помощь!

Спасибо,

Майк


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));

Ответы [ 2 ]

0 голосов
/ 25 ноября 2010

Просто используйте P / Invoke из C ++ / CLI. См. здесь для получения дополнительной информации.

0 голосов
/ 25 ноября 2010

Вы не можете избавиться от Marshalling в обоих направлениях, поскольку оба типа строк (управляемая строка и собственный wchar *) принципиально различаются.Кроме того, GC необходимо отслеживать выделенные управляемые ресурсы, и поэтому вам всегда нужно будет создавать System::String^ объект для отправки обратно в управляемый мир.

...