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

标签 c pointers reference

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

作为完整性检查,我用“vanilla”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);
}

对于 refFunc.c

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

对于 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);
}

最后,我用来编译和运行 mex 的命令以及我得到的输出

>> mex refFunc.c valFunc.c -c
Building with 'MinGW Compiler (C)'.
MEX completed successfully.
>> mex mainmex.c refFunc.obj valFunc.obj
Building with 'MinGW Compiler (C)'.
MEX completed successfully.
>> mainmex
executing valFunc, answer is 10
executing valFunc, ...
------------------------------------------------------------------------
          Access violation detected at Thu

当我切换到 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 函数调用都是按值传递的;在某些情况下,例如这个,参数是指针(按值传递)。

关于c - 为什么通过引用调用的函数在从 mex 包装器中的其他源文件链接时不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38376968/

相关文章:

c++ - C++ 中指针和引用的问题

找不到有效引用

c - 如何使控制台应用程序接收 100,000 个整数的输入

c - C 中 malloc 的惯用宏?

成功分配指针后,无法将值分配给结构指针

C - 使用指针创建更高效​​的循环来遍历字母表

c++ - std::iterator::reference 必须是引用吗?

c - c中按位编程的奇怪结果

c - 无效写入 Valgrind

c - Linux/C : Writing command-line arguments to a text file as separate lines?