在const的指针数组中抛出const-ness,以及关于C的其他问题

时间:2009-04-20 02:54:05

标签: c arrays pointers casting const

我正在运行一些代码来测试MATLAB mex函数中的多线程(我知道MATLAB不是线程安全的......我只是在玩,看看会发生什么)。 MATLAB C代码函数的入口点在帖子底部剪切的代码中具有mexFunction函数的签名。因为我想基本上将这个函数的参数传递给使用pthreads创建的另一个线程,所以我需要将所有内容捆绑到一个结构中。 mexFunction的签名(我无法更改)包含一个指向mxArray的指针数组,但是我不能在结构定义中直接包含指向mxArray的指针数组,因为那时我无法分配给结构的那个字段(无法分配给数组)。例如,这不起作用:

typedef struct MexFunArgs {
  int nrhs;
  const mxArray *prhs[];
} MexFunArgs;

/* ... now within the mexFunction ... */

MexFunArgs mfa;

mfa.prhs = prhs;

首先想到解决这个问题的方法是将结构定义更改为:

typedef struct MexFunArgs {
  int nrhs;
  const mxArray **prhs;
} MexFunArgs;

然而,当我在另一个线程中使用这个结构时,我需要强制转换为一个指针数组,以便将它传递给mexCallMATLAB函数,据我所知,这个函数无法完成(请如果我错了,请纠正我!)。

所以,我想我会改变结构定义:

typedef struct MexFunArgs {
  int nrhs;
  const mxArray *(*prhs)[];
} MexFunArgs;

即,指向mxArray指针数组的指针。这解决了赋值问题(尽管编译器仍然因为我不理解的原因而抱怨不兼容的指针类型)。但是,事实证明,mexCallMATLAB函数不接受指向const mxArrays的指针数组,而是指向非const mxArrays的指针数组。所以现在我想知道是否有一种方法可以将指针的const方面转换为指向const mxArrays的指针数组。我不知道怎么做......以下是不合法的:

(mxArray *(*)[])

可以吗?如果没有,那么我正在尝试做什么(将这些参数传递给另一个没有受到破坏的其他线程,以便在没有编译器抱怨的情况下可以使用它们)在C中以其他方式可能?

以下是我目前正在使用的完整代码,它按预期运行,但在编译时会产生警告。我讨厌警告,并希望它消失。实现这一目标的正确方法是什么?

#include <pthread.h>
#include <unistd.h>
#include <mex.h>

typedef struct MexFunArgs {
  int nrhs;
  mxArray *(*prhs)[];
} MexFunArgs;

void *do_thread(void *args) {
  MexFunArgs *mfa = (MexFunArgs*) args;

  mexCallMATLAB(0, NULL, mfa->nrhs, *mfa->prhs, "disp");

  pthread_exit(NULL);
}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  int num;

  if (nrhs < 1)
    mexErrMsgTxt("not enough input arguments");
  else
    num = mxGetScalar(prhs[0]);

  MexFunArgs mfa;

  mfa.nrhs = nrhs;
  mfa.prhs = &prhs[1]; /* <-- threads.c:29: warning: assignment from incompatible pointer type */

  pthread_t threads[num];

  int rc, t;
  for (t = 0; t < num; t++) {
    mexPrintf("In main: creating thread %d\n", t);
    rc = pthread_create(&threads[t], NULL, do_thread, (void *) &mfa);
    if (rc)
      mexErrMsgTxt("Problem with return code from pthread_create()");
  }
  return;
}

3 个答案:

答案 0 :(得分:1)

警告是由于

的分配
  

指向const mxArray s

的指针的数组(名称)

  

指向非const mxArray指针数组的指针。

请记住,您只能安全地分配更有资格的类型。

这些是不同的类型。您要么禁用该特定行的警告,要么使用强制转换 - 两者都同样危险。

另请注意,如果使用基于C99的编译器进行编译,则mxArray声明中的结构为空[],声明一个可变长度数组。这是你想要的吗?

答案 1 :(得分:1)

想出让一切都快乐起来的方法。因为在函数签名中对数组和指针的处理方式相同,所以我只是将mexFunction改为mxArray **而不是mxArray * thing []。然后没有问题转换,因为不需要转换为数组类型(非法)。

答案 2 :(得分:0)

根据你的标题进行疯狂猜测我假设你还没有掌握指针的常量与它所指向的对象的常数之间的差异。

有关可以指导您的示例,请参阅Why does this allow promotion from (char *) to (const char *)?

对于和其他问题部分,为什么不将它们分成单独的问题。这可能有助于获得您寻求的答案。