C 为什么通过引用调用的函数在从mex包装中的其他源文件链接时不起作用?

C 为什么通过引用调用的函数在从mex包装中的其他源文件链接时不起作用?,c,pointers,reference,C,Pointers,Reference,我已经在两个单独的.c文件中编写了两个函数“refFunc”和“valFunc”,并带有头文件。我试图将它们与mex包装函数“mainmex”一起编译,并将它们链接在一起以形成一个mex可执行文件。函数“refFunc”接受一个“int”并返回该整数乘以2的结果。函数“valFunc”做同样的事情,只是它通过引用调用,而不是通过值调用,并且它不返回任何内容valFunc'执行得很好,但'refFunc'会导致访问冲突 作为一个理智的检查,我用一个“香草”c包装器“mainc”重复了相同的步骤。函

我已经在两个单独的.c文件中编写了两个函数“refFunc”和“valFunc”,并带有头文件。我试图将它们与mex包装函数“mainmex”一起编译,并将它们链接在一起以形成一个mex可执行文件。函数“refFunc”接受一个“int”并返回该整数乘以2的结果。函数“valFunc”做同样的事情,只是它通过引用调用,而不是通过值调用,并且它不返回任何内容valFunc'执行得很好,但'refFunc'会导致访问冲突

作为一个理智的检查,我用一个“香草”c包装器“mainc”重复了相同的步骤。函数执行得很好,没有任何问题。Matlab中是否存在导致这种情况的怪癖?还是我做错了什么

这是mainmex.c的代码

#include "mex.h"
#include "valFunc.h"
#include "refFunc.h"
#include <stdio.h>


void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    printf("executing valFunc, answer is %i\n", valFunc((int)5));
    int *b;
    *b = 0;
    printf("executing valFunc, ...");
    refFunc((int)5, b);
    printf("b is %i\n", *b);
}
和valFunc.c

#include "valFunc.h" /*Doesn't seem to make a difference whether or not I 
                     include the header file*/
int valFunc(int a)
{
    int b = a * 2;
    return b;
}
和refFunc.h

void refFunc(int a, int *b);
和valFunc.h

int valFunc(int a);
和mainc.c

#include "valFunc.h"
#include "refFunc.h"
#include <stdio.h>

void main()
{
    printf("executing valFunc, answer is %i\n", valFunc((int)5));
    int *b;
    *b = 0;
    printf("executing valFunc, ...");
    refFunc((int)5, b);
    printf("b is %i\n", *b);
}
当我切换到bash时,我做了以下操作,得到了以下结果:

$ gcc mainc.c valFunc.obj refFunc.obj -fno-use-linker-plugin
$ ./a.exe
executing valFunc, answer is 10
executing valFunc, ...b is 10
请注意,我甚至使用了在matlab中工作时遗留下来的相同.obj文件。

mexFunc()
声明了一个指针,但未能初始化它。此指针的值不确定。然后将该指针传递到
refFunc()
,该指针尝试将其结果写入指针指向的(不确定)位置。这表现出未定义的行为

mexFunction()
应该执行以下操作:

void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    int b;                   // declare b as int, not int *
    refFunc((int)5, &b);     // pass the address of b
    printf("b is %i\n", b);  // b's value has been set
}

还要注意的是,C既没有作为各种数据类型的引用,也没有按引用传递的调用语义。所有C函数调用都是按值传递的;在某些情况下,如本例中,参数是指针(通过值传递)。

这与Matlab或mex无关。这只是遇到问题的环境。标签被编辑了,工作起来很有魅力。感谢您的回复。实际上,在OP的原始代码中,他声明了未初始化的指针b,然后尝试用
*b=0解除对它的引用在调用refFunc()之前,这很容易就在那里崩溃。没错,@FredK。我已经更新了我的答案,以便更准确地描述情况,尽管不需要更改建议的更正。
$ gcc mainc.c valFunc.obj refFunc.obj -fno-use-linker-plugin
$ ./a.exe
executing valFunc, answer is 10
executing valFunc, ...b is 10
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    int b;                   // declare b as int, not int *
    refFunc((int)5, &b);     // pass the address of b
    printf("b is %i\n", b);  // b's value has been set
}