Я делаю небольшую оболочку из научной библиотеки (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?