0

I'm using a C++ header library to load stl files to later render them in a VR sample script. Basically, I use the parse_stl library that I found GitHub. The library is included in my main include file. This file handles several structures like: TriangleSet (this one generates the triangle models, with their coordinates and colors) and Scene (which uses TriangleSet and handles the rendering).

I need to call the function loadSTLModel from a void function in the Scene structure. The loadSTLModel is a void in TriangleSet, which later calls stl::parse_stl. This function takes the filename as a std::string (apparently), but it is giving me linking errors that I can't understand. The library works fine I've tested it before, and I've managed to use it in a similar sample but that was more complex and I haven't been able to pass the argument properly in this example. It's clear to me that the error is due to how I pass the filepath variable to the different functions, but I don't know how to fix it.

Here's the error code:

main.obj : error LNK2019: unresolved external symbol "struct stl::stl_data __cdecl stl::parse_stl(class std::basic_string,class std::allocator > const &)" (?parse_stl@stl@@YA?AUstl_data@1@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: void __thiscall TriangleSet::loadSTLModel(char const *,unsigned int,struct DirectX::XMFLOAT3,struct DirectX::XMFLOAT3)" (?loadSTLModel@TriangleSet@@QAEXPBDIUXMFLOAT3@DirectX@@1@Z)

main.h

struct TriangleSet{
   ...
   void loadSTLModel(const char* filename, uint32_t color, XMFLOAT3 origin, XMFLOAT3 size) {

        XMFLOAT3 s = multXMFLOAT(size, XMFLOAT3(0.5,0.5,0.5));
        XMFLOAT3 o = origin;

        std::string stl_filename = filename;
        auto stlData = stl::parse_stl(stl_filename);
        ...
   }
   ...
}

struct Scene{
  ...

  void Init(){
     ...
     TriangleSet furniture;
        std::string FilePathName = "C:/sampleSTL.stl";
        XMFLOAT3 Origen = { 0.0f, 0.0f, 0.0f };
        XMFLOAT3 Escala = { 1.0f, 1.0f, 1.0f};
        furniture.loadSTLModel(FilePathName.c_str(),0xff383838, Origen,     Escala);
     ...

}

parse_stl.h

namespace stl {
    struct stl_data {
    std::string name;
    std::vector<triangle> triangles;

    stl_data(std::string namep) : name(namep) {}
  };

  stl_data parse_stl(const std::string& stl_path);
}

parse_stl.cpp

namespace stl {
    ...
    stl_data parse_stl(const std::string& stl_path) {
    std::ifstream stl_file(stl_path.c_str(), std::ios::in | std::ios::binary);
    if (!stl_file) {
      std::cout << "ERROR: COULD NOT READ FILE" << std::endl;
      assert(false);    
    }

    char header_info[80] = "";
    char n_triangles[4];
    stl_file.read(header_info, 80);
    ...
    ...

    return info;
  }

}
Manu Sisko
  • 269
  • 2
  • 17
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Justin May 18 '18 at 23:53
  • You have the non-static member function `std_data::parse_stl`, but you call the `stl::parse_stl` function. What is `stl`? Is it a namespace? Is it a class or structure? Is `parse_stl` a member of the `stl` namespace (if it's a namespace) or is it a `static` member function of the `stl` class or structure (if it's a class or structure)? There's a reason you should learn how to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve), so we don't have to guess about these things. – Some programmer dude May 18 '18 at 23:54
  • Oh yes I missed that part, stl is a namespace and stl_data is a structure in stl. – Manu Sisko May 18 '18 at 23:57
  • Then think about what you're doing. Should the `parse_stl` function be a non-static member function of `stl_data`? Maybe it should be a `static` member function? Or maybe it should be a member of the `stl` namespace instead (because that's how you call it like now). – Some programmer dude May 19 '18 at 00:00
  • Yes, sorry I had edited the code in parse_stl.h incorrectly, I've edited it. parse_stl is a member of the stl namespace that returns a stl_data structure. – Manu Sisko May 19 '18 at 00:08
  • Then in your source file (`parse_stl.cpp`), is the `parse_stl` function inside the `stl` namespace as well? – Some programmer dude May 19 '18 at 00:10
  • Yes, it is there. – Manu Sisko May 19 '18 at 00:12
  • Instead of me (or others) having to ask all these questions, ***please*** learn how to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve)! It helps us *a lot!* Also please [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask), and probably [this SO question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/) as well. And to be on the safe side, all of http://idownvotedbecau.se/ too. – Some programmer dude May 19 '18 at 00:14
  • Now for my (possibly) last question, is the file `parse_stl.cpp` in your Visual Studio project? You do actually build with it? If you modify the source file and build, is Visual Studio listing it when building? – Some programmer dude May 19 '18 at 00:15
  • Sorry friend, I'm new to the site. Will check out the Link and come back when I learn it. Thanks! – Manu Sisko May 19 '18 at 00:16
  • Yes, it is there. If I modify it VS compiles the modifications. – Manu Sisko May 19 '18 at 00:18
  • @ManuSisko -- First, do you understand that the issue is not a compiler error? The issue is a linker error -- the compiler has already done its work, compiling each of your modules to .obj files. You now have to see if the *linker* knows anything about your compiled modules. So either something is not right or is incomplete with your project's linker settings, or you're not specifying the library to the linker in your project, or some other linker related issue. – PaulMcKenzie May 19 '18 at 00:40
  • Yes, the linker sees the library, If I execute the stl::parse_stl function from my main,cpp mainloop it executes correctly, The problem happends when I call it from a structure void function. – Manu Sisko May 19 '18 at 00:43
  • @ManuSisko -- `main.obj : error LNK2019:` -- So where is `main.cpp` or `main.cxx` etc.? Somewhere you compiled a source module called `main.cpp`, but you didn't post that source file. That error is showing where you're calling the function at issue. I know the linker error may seem confusing, but break it down step-by-step and it tells you which source file is calling this function that doesn't exist. – PaulMcKenzie May 19 '18 at 00:44
  • Seems that you are missing to link the library – florgeng May 18 '18 at 23:50

1 Answers1

0

I've managed to make it work. The problem was that the linker was not looking for the parse_stl function inside the stl namespace in parse_stl.cpp. Even though Visual Studio compiled the code in parse_stl.cpp and that it was included in the project, for some reason the linker did not attempt to use the file.

So I managed to make it work by moving the entire 'stl' namespace to my main.cpp file, so now the linker can properly find the functions.

Manu Sisko
  • 269
  • 2
  • 17