Bind void * указатель на C ++ / Cli указатель элементарного типа - PullRequest
0 голосов
/ 18 мая 2011

Я делаю небольшую оболочку из научной библиотеки (http://root.cern.ch) из неуправляемого в управляемый мир, используя C ++ cli.

Чтение специального формата файла (который является основной целью) осуществляется через:
1) Один раз за всю жизнь вызов SetBranchAddress (const char name, void * outputVariable) , чтобы сообщить ему адрес вашей переменной
2) Чем вы N раз звоните GetEntry (ulong numberOfRow) , который заполняет void * outputVariable соответствующим значением;

Я поставил этот пример использования:

double myValue; //this field will be filled

//We bind myValue to the 'column' called "x" stored in the file"
TTree->SetBranchAddress("x", &myValue); 

// read first "entry" (or "row") of the file
TTree->GetEntry(0); 

// from that moment myValue is filled with value of column "x" of the first row
cout<<"First entry x = "<<myValue<<endl; 

TTree->GetEntry(100); //So myValue is filled with "x" of 101 row
...

Таким образом, в коде C ++ / CLI проблема заключается в привязке управляемых элементарных типов к этому указателю void *;

Я пробовал 3 подхода:

namespace CppLogicLibrary {
public ref class SharpToRoot
{        
       double mEventX;
       double *mEventY;
       IntPtr memEventZ;

       ///Constructor
       SharpToRoot()
       {
          mEventy = new double();
          memEventZ= Marshal::AllocHGlobal(sizeof(double));
       }

       void SetBranchAddresses()
       {
           pin_ptr<double> pinnedEventX = &mEventX;
           mTree->SetBranchAddress("ev_x", pinnedEventX);
           mTree->SetBranchAddress("ev_y", mEventY);
           mTree->SetBranchAddress("ev_z", memEventZ.ToPointer());
           ...
           //now I read some entry to test... just in place
           mTree->GetEntry(100);
           mTree->GetEntry(101);
           double x = mEventX;
           double y = *mEventY
           double z = (double)Marshal::PtrToStructure(memEventZ, Double::typeid);
       }

       ...

Все 3 варианта скомпилированы без ошибок, идут без исключений ... НО заполняет свои значения (void *) каким-то мусорным значением, таким как 5,12331E-305. В неуправляемом коде все работает нормально.

В чем может быть ошибка при такой привязке void * к элементарным типам C ++ / CLI?

1 Ответ

0 голосов
/ 25 мая 2011

Проблема заключалась в том, что внутренне данные были представлены поплавками внутри этой библиотеки.Таким образом, когда он был отображен и обработан как double на стороне C #, он дал 5,12331E-305.

Каждый из этих 3 вариантов работал.И, с моей точки зрения, использование pin_ptr pinnedEventX = & mEventX;в этом случае был неправильным, потому что не сохраняется между выполнением функций;

Что я не уверен, почему эта ситуация с плавающей точкой была обработана в родном C ++.Как я уже писал, проблем не было.

...