Явно устанавливая значение указателя - PullRequest
7 голосов
/ 08 августа 2011

Я пишу mex-файл (используя C ++), который будет принимать адрес памяти в качестве ввода и работать с данными по этому адресу памяти.Поскольку я вынужден использовать MATLAB в качестве среды, моя программа может принимать только типы данных MATLAB в качестве входных данных (char, bool, float, double и int).Как я могу назначить свое входное значение указателю?

Псевдокод:

// Outside of program
// double input_arg = hex2dec('00C2E4E8')

double *pointer;
pointer = (double *)input_arg;
// pointer == hex2dec('00C2E4E8')

По сути, это может быть воспринято как жесткое кодирование значения указателя, похожего на:

double *pointer = (double *)hex2dec('00C2E4E8');

Я получаю сообщение об ошибке:

ошибка C2440: '=': невозможно преобразовать из 'double' в 'double *'

У меня естьтакже пытался использовать static / const / reinterpret / dynamic_cast, но я не очень понимаю, как они работают (и я не мог заставить их работать).Можно ли вообще вручную назначать значения адресов памяти указателям?

Ответы [ 4 ]

6 голосов
/ 08 августа 2011

Кажется, что вы не можете использовать double, который является типом с плавающей запятой, в качестве представления адреса в памяти, который по своей сути является целочисленным значением.

Полагаю, ваш input_arg должен быть определен как тип MATLAB int, а не как double.

5 голосов
/ 08 августа 2011

То, что вы пытаетесь сделать, опасно, потому что вы передаете необработанные указатели в некоторый код C ++, делаете предположения о том, что существует в этом месте и выполняете код, основываясь на этих предположениях. Но допустим, вы позаботились обо всех этих проблемах безопасности.

Возможно, вы захотите передать указатель на ваш MEX-файл как UINT64 (чтобы код можно было перекомпилировать и использовать как в 64-битной установке MATLAB).

На стороне MATLAB:

ptrArg = uint64(hex2dec( '00C2E4E8' ));
myMexFile( ptrArg );

В вашей функции mex:

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if( nrhs < 1 ) {
    // error

  } else {
    // Verify that the address argument is a UINT64 
    if( mxGetClassID( prhs[0] ) != mxUINT64_CLASS ) {
      // error

    }
  }

  // Done with error checking, now perform the cast
  uint64_T mlData = *static_cast<unsigned long long *>( mxGetData( prhs[0] ) );
  double *p = reinterpret_cast<double *>( mlData );

  // Do whatever with p
}

Примечание: Вы можете сделать то же самое с двойным, просто измените проверку mxGetClassID, чтобы найти mxDOUBLE_CLASS. В этом случае приведенное выражение становится:

double *p = reinterpret_cast<double *>( *mxGetPr( prhs[0] ) );

EDIT:
То, что я сказал о том, чтобы заставить этот код работать на 32- или 64-битной машине, верно только в том случае, если обе машины имеют порядок байтов. В противном случае, если вы передадите 32-разрядный указатель в 64-разрядном коде uint на машине с прямым порядком байтов и приведете его к double *, вы получите указатель, равный 0x00000000.

Вы можете справиться с проблемами порядка байтов с помощью функции MATLAB computer для определения порядка машин. Если требуется замена байтов, вы можете использовать swapbytes. Для выполнения этих функций из вашего кода C ++ используйте mexCallMATLABWithTrap.

5 голосов
/ 08 августа 2011

Почему input_arg удваивается? Указатели всегда имеют целочисленный тип.

Это может решить "преобразование двойного в двойное *"

5 голосов
/ 08 августа 2011

Попробуйте:

double *pointer = (double *)0x00C2E4E8;

(добавьте 0x)

...