Eric Miller
Eric Miller

Reputation: 110

Linking header files: Matlab Engine and OpenGL

I'm trying to make a C program that interfaces with Matlab via the Matlab Engine, and which also utilizes OpenGL via Glut. I have successfully compiled and run C programs that do one of these things (Matlab Engine OR Glut), but I am having trouble compiling a program that uses both.

In particular, I am using the following command with gcc: gcc -o test test.c -I/Applications/MATLAB_R2014a.app/extern/include/ -framework GLUT -framework OpenGL. The -I flag is to tell link to the directory where the engine.h and matrix.h header files are located. The compiler complains that the Matlab Engine and matrix library functions are undefined symbols:

Undefined symbols for architecture x86_64:
  "_engEvalString", referenced from:
      _main in test-bae966.o
  "_engGetVariable", referenced from:
      _main in test-bae966.o
  "_engOpen", referenced from:
      _main in test-bae966.o
  "_engPutVariable", referenced from:
      _main in test-bae966.o
  "_mxCreateDoubleScalar", referenced from:
      _main in test-bae966.o
  "_mxGetPr", referenced from:
      _main in test-bae966.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Here is the test.c file that I'm trying to compile. I don't need it to do anything in particular right now. First, I just want to see if I can make a C program use both Matlab Engine and OpenGL.

#include <GLUT/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <engine.h>
#include <matrix.h>

void display(void)
{
    /* clear all pixels */
    glClear(GL_COLOR_BUFFER_BIT);
    /* draw white polygon (rectangle) with corners at
     * (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0)
     */
    glColor3f(1.0, 1.0, 1.0);
    glBegin(GL_POLYGON);
    glVertex3f(0.25, 0.25, 0.0);
    glVertex3f(0.75, 0.25, 0.0);
    glVertex3f(0.75, 0.75, 0.0);
    glVertex3f(0.25, 0.75, 0.0);
    glEnd();
    /* don’t wait!
     * start processing buffered OpenGL routines
     */
    glFlush();
}

void init(void)
{
    /* select clearing (background) color */
    glClearColor(0.0, 0.0, 0.0, 0.0);
    /* initialize viewing values */
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}

/*
 * Declare initial window size, position, and display mode
 * (single buffer and RGBA). Open window with “hello”
 * in its title bar. Call initialization routines.
 * Register callback function to display graphics.
 * Enter main loop and process events.
 */
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(250, 250);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("hello");
    init();

    Engine *ep;
    mxArray *pa = NULL, *res = NULL;

    if (!(ep = engOpen(""))) {
            fprintf(stderr, "\nCan't start MATLAB engine\n");
            return EXIT_FAILURE;
        }

    pa = mxCreateDoubleScalar(5);
    engPutVariable(ep, "a", pa);
    engEvalString(ep, "res = 2 * a");
    res = engGetVariable(ep,"res");
    int resVal = *mxGetPr(res);
    printf("%d\n", resVal);

    glutDisplayFunc(display);
    glutMainLoop();
    return 0; /* ISO C requires main to return int. */
}

Upvotes: 0

Views: 253

Answers (1)

John Bollinger
John Bollinger

Reputation: 181104

You have a linker error. You need to tell gcc the name and location of the file(s) containing MATLAB functions your program is trying to call. You would add an -L option specifying the directory, and afterward an -l option specifying the file.

For example, if the needed library were /Applications/MATLAB_R2014a.app/extern/lib/libengine.dylib then you would add -L/Applications/MATLAB_R2014a.app/extern/lib -lengine to the compile command.

This sort of thing gets old quickly, so one generally writes a script -- or better, a Makefile -- so you don't have to retype all that mess every time.

Upvotes: 0

Related Questions