明确定义指针的值

7
我正在编写一个 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');

我收到了这个错误:
``` error C2440: '=' : 无法从“double”转换为“double *” ```
我也尝试使用static/const/reinterpret/dynamic_cast,但我不太理解它们的工作原理(而且我也无法让它们工作)。手动分配内存地址值给指针可能吗?

如果这是一个地址,为什么要使用 double 呢?在 C 语言中,你可以将一个整数类型强制转换成指针类型,但可能会警告整数类型与指针类型的大小不同。 - Matt K
4
请注意,对于下面回答的每个人,请不要仅仅因为问题标记为C&C ++而开始发表您的意见,就此认为OP出现错误!这个问题是关于MATLAB和MEX文件以及如何在MATLAB和C ++之间传递数据的。当涉及到这一点时,并不总是可能保证类型安全。 - Praetorian
4个回答

6

看起来你不能使用double,它是一种浮点类型,作为内存地址的表示,内存地址本质上是整数值。

我猜你的input_arg应该定义为MATLAB的int类型,而不是double


这解决了问题。我一开始使用了一个双精度浮点数,因为这是MATLAB默认的类型,但我没有想到我可以将整数强制转换为指针,而不是双精度浮点数。 - Brian

5

您正在尝试做的事情是危险的,因为您正在向某些C++代码传递原始指针,对该位置上存在的内容进行假设,并根据这些假设执行代码。但是假设您已经注意到了所有这些安全问题。

您可能希望将指针作为UINT64传递给您的MEX文件(以便可以重新编译该代码并在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
}
< p > < em > 注意: 您也可以使用双精度来完成相同的操作,只需更改 mxGetClassID 检查以查找 mxDOUBLE_CLASS 即可。在这种情况下,强制转换表达式变为:

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

编辑:
如果32位或64位的机器都是小端序,那么我所说的能够使这段代码工作的说法才是正确的。否则,在大端序的机器上,如果你将一个32位指针传递到64位的uint上,并将其强制转换为double *,你将得到一个指针,其值为0x00000000

你可以通过使用MATLAB函数computer来处理字节序问题,以检测机器字节序。如果需要进行字节交换,则可以使用swapbytes。要从C++代码中执行这些函数,请使用mexCallMATLABWithTrap


2
这也不完全正确。mxGetData返回指向由Matlab分配的Matlab数组中数据数组的指针,而不是其第一个元素的值。您需要另一步解引用,例如(*(mxGetData(prhs[0])))。如果在32位上运行,reinterpret_cast将是错误的,因为它将把uint64的上半部分和下半部分划分为32位指针值。需要将该值复制到int中,或者假定调用者将传递与sizeof(void*)相同宽度的地址值并使用typedefs。 - Andrew Janke
@Andrew Janke 感谢你指出需要进行额外解引用的问题。而且在你发表评论之前的几秒钟,我已经纠正了关于大端机器上64位值的部分错误。 - Praetorian
字节序问题实际上没有让我想到 - 我已经有一段时间没有遇到大端机器了 - 但是我在考虑如果 OP 想要扩展签名以接受地址数组会发生什么。看起来只需像您所做的那样将输入复制到 mlData 或小心地处理数组索引(在转换之前进行索引)即可解决它。+1 - Andrew Janke

5
尝试: double *指针 = (double *)0x00C2E4E8; (添加0x)

从我阅读的文本来看,似乎OP并不是试图将一个文字地址放入double *中,而是将函数参数放入double *中。 - Matt K
这个答案完全错误(是的,语法是正确的,但这不是OP所问的)。 - Praetorian
原始帖子已经编辑过了,为了更清晰明了。我试图传递十进制值,但是收到了错误信息。 - Brian

5

为什么input_arg是double类型?指针总是某种整数类型。

这可能解决“将double转换为double *”的问题。


指针从来不会是某种整数类型,它们是指针类型。(在大多数系统上,将整数转换为指针或将指针转换为整数可能是有意义的。) - Keith Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接