embed-resource


  • Gesperrt

    Habe den Fehler vermutlich gefunden. Das Problem lag gar nicht an den Pfaden. Es fehlte vermutlich eine boost dll boost_filesystem-vc141-mt-gd-x64-1_69.dll.

    Wollte fragen ob jemand elegante Lösungen kennt, die dll nicht "von Hand" kopieren zu müssen.


  • Gesperrt

    Die jetzige Fehlermeldung:

    >------ Build started: Project: CMakeLists, Configuration: Debug ------
      [1/6] C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1424~1.283\bin\HostX64\x64\cl.exe  /nologo /TP  -ID:\code\boost -I..\..\..\ext\embed-resource /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Zi /Ob0 /Od /RTC1 /showIncludes /Foext\embed-resource\CMakeFiles\embed-resource.dir\embedresource.cpp.obj /Fdext\embed-resource\CMakeFiles\embed-resource.dir\ /FS -c ..\..\..\ext\embed-resource\embedresource.cpp
      [2/6] cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=ext\embed-resource\CMakeFiles\embed-resource.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100177~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100177~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1424~1.283\bin\Hostx64\x64\link.exe /nologo ext\embed-resource\CMakeFiles\embed-resource.dir\embedresource.cpp.obj  /out:ext\embed-resource\embed-resource.exe /implib:ext\embed-resource\embed-resource.lib /pdb:ext\embed-resource\embed-resource.pdb /version:0.0  /machine:x64 /debug /INCREMENTAL /subsystem:console -LIBPATH:D:\code\boost\stage\lib D:\code\boost\stage\lib\boost_filesystem-vc141-mt-gd-x64-1_69.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
      [3/6] C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1424~1.283\bin\HostX64\x64\cl.exe  /nologo  -ID:\code\boost -I..\..\..\ext\embed-resource /DWIN32 /D_WINDOWS /W3 /MDd /Zi /Ob0 /Od /RTC1 /showIncludes /FoCMakeFiles\embedtest.dir\shaders\frag.glsl.c.obj /FdCMakeFiles\embedtest.dir\ /FS -c shaders\frag.glsl.c
      [4/6] C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1424~1.283\bin\HostX64\x64\cl.exe  /nologo  -ID:\code\boost -I..\..\..\ext\embed-resource /DWIN32 /D_WINDOWS /W3 /MDd /Zi /Ob0 /Od /RTC1 /showIncludes /FoCMakeFiles\embedtest.dir\shaders\vert.glsl.c.obj /FdCMakeFiles\embedtest.dir\ /FS -c shaders\vert.glsl.c
      [5/6] C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1424~1.283\bin\HostX64\x64\cl.exe  /nologo /TP  -ID:\code\boost -I..\..\..\ext\embed-resource /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Zi /Ob0 /Od /RTC1 /showIncludes /FoCMakeFiles\embedtest.dir\src\main.cpp.obj /FdCMakeFiles\embedtest.dir\ /FS -c ..\..\..\src\main.cpp
      [6/6] cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\embedtest.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100177~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100177~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1424~1.283\bin\Hostx64\x64\link.exe /nologo CMakeFiles\embedtest.dir\src\main.cpp.obj CMakeFiles\embedtest.dir\shaders\vert.glsl.c.obj CMakeFiles\embedtest.dir\shaders\frag.glsl.c.obj  /out:embedtest.exe /implib:embedtest.lib /pdb:embedtest.pdb /version:0.0  /machine:x64 /debug /INCREMENTAL /subsystem:console -LIBPATH:D:\code\boost\stage\lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
      FAILED: embedtest.exe 
      cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\embedtest.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100177~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100177~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1424~1.283\bin\Hostx64\x64\link.exe /nologo CMakeFiles\embedtest.dir\src\main.cpp.obj CMakeFiles\embedtest.dir\shaders\vert.glsl.c.obj CMakeFiles\embedtest.dir\shaders\frag.glsl.c.obj  /out:embedtest.exe /implib:embedtest.lib /pdb:embedtest.pdb /version:0.0  /machine:x64 /debug /INCREMENTAL /subsystem:console -LIBPATH:D:\code\boost\stage\lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
      LINK Pass 1: command "C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1424~1.283\bin\Hostx64\x64\link.exe /nologo CMakeFiles\embedtest.dir\src\main.cpp.obj CMakeFiles\embedtest.dir\shaders\vert.glsl.c.obj CMakeFiles\embedtest.dir\shaders\frag.glsl.c.obj /out:embedtest.exe /implib:embedtest.lib /pdb:embedtest.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console -LIBPATH:D:\code\boost\stage\lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\embedtest.dir/intermediate.manifest CMakeFiles\embedtest.dir/manifest.res" failed (exit code 1120) with the following output:
    D:\code\embed_resource_test\out\build\x64-Debug\main.cpp.obj : error LNK2001: unresolved external symbol "char const * const _resource_vert_glsl" (?_resource_vert_glsl@@3QBDB)
        Hint on symbols that are defined and could potentially match:
          _resource_vert_glsl
    D:\code\embed_resource_test\out\build\x64-Debug\main.cpp.obj : error LNK2001: unresolved external symbol "unsigned __int64 const _resource_vert_glsl_len" (?_resource_vert_glsl_len@@3_KB)
        Hint on symbols that are defined and could potentially match:
          _resource_vert_glsl_len
    D:\code\embed_resource_test\out\build\x64-Debug\embedtest.exe : fatal error LNK1120: 2 unresolved externals
      ninja: build stopped: subcommand failed.
    

    Z.B. diese Symbol wird gesucht unsigned __int64 const _resource_vert_glsl_len
    so sieht es vor dem kompilieren aus const size_t _resource_vert_glsl_len = sizeof(_resource_vert_glsl);

    Beim Nachschauen von size_t fehlt vermutlich zum Teil _WIN64 Habe es mit x86 kompiliert und der Fehler kommt immer noch.

    // Definitions of common types
    #ifdef _WIN64
        typedef unsigned __int64 size_t;
        typedef __int64          ptrdiff_t;
        typedef __int64          intptr_t;
    #else
        typedef unsigned int     size_t;
        typedef int              ptrdiff_t;
        typedef int              intptr_t;
    #endif
    

    Oder doch nicht? Die object-files existieren eigentlich. Weiss jemand wo der Fehler liegt oder liegen könnte?

    Edit: Ist die Differenz (?_resource_vert_glsl@@3QBDB) zu _resource_vert_glsl der Grund? Woher kommt die Differenz?



  • Du scheinst da C und C++ zu mischen. Stichwort Name Mangling (s. 1.2.4 Handling of C symbols when linking from C++).


  • Gesperrt

    @Th69 Danke für die Antwort.

    Das Problem mit dem dll habe ich vorläufig gelöst mit set(Boost_USE_STATIC_LIBS ON)

    set(Boost_USE_STATIC_LIBS ON)
    
    find_package(Boost REQUIRED)
    include_directories(${Boost_INCLUDE_DIRS})
    #message("${Boost_INCLUDE_DIRS}")
    link_directories(${Boost_LIBRARY_DIRS})
    #message("${Boost_LIBRARY_DIRS}")
    

    Wegen dem Linker error habe ich versucht

    • die Zeile set(out_f "${PROJECT_BINARY_DIR}/${in_f}.c") in set(out_f "${PROJECT_BINARY_DIR}/${in_f}.cpp") zu ändern
    • in Resource.h extern "C" vor das Macro LOAD_RESOURCE zu schreiben
    • add_compile_options("/TP") zu verwenden

    Brachte alles nichts, langsam bin ich mich am fragen, ob es anstelle embed-resource nicht eine bessere Möglichkeit gibt.


  • Gesperrt

    Bin am versuchen dem Fehler näher zu kommen.

    Dafür habe ich eine Testvariable in einer Quelldatei test.symbol.cpp definiert:

    int testsymbol = 345;
    

    Und die Quelldatei in das gleiche Verzeichnis getan, wie die fehlerverursachenden Quelldateien.
    CMakeLists:

    list(APPEND MyResources D:/code/embed_resource_test/out/build/x64-Debug/shaders/test.symbol.cpp)
    
    message("MyResources ${MyResources}")
    
    add_executable(embedtest D:/code/embed_resource_test/src/main.cpp ${MyResources})
    

    Die main function:

    int main()
    {
    	std::cout << "test embed resource" << '\n';
    
    	extern int testsymbol;
    	std::cout << testsymbol << '\n';
    }
    

    Das kompiliert ohne Fehlermeldung und macht die erwartete Ausgabe. Auch wenn ich int mit size_t ersetze, kommt keine Fehlermeldung und die erwartete Ausgabe.

    Wenn ich aber noch jeweils const hinzuschreibe, kommt die unresolved external symbol Fehlermeldung.

    Edit: Fand unter mixing-extern-and-const:

    Um, since const s are implicitly static, you need an extern even on the a_global_var definition
    (in file.c). Without this, anything that includes file.h will not link because it is looking for a 
    const int a_global_var with external linkage. – user123456
    

    Habe extern auch bei der Definition hinzugeschrieben, jetzt geht es auch mit const.



  • const hat in C++ internal linkage, s.a. Why does const imply internal linkage in C++, when it doesn't in C?
    Üblicherweise werden daher Konstanten in Headerdateien gepackt und diese dann eingebunden (Konstanten in C++ werden quasi 'inplace' verwendet).

    In C dagegen sind mit const versehene Variablen einfach nur (globale) schreibgeschützte Variablen.


  • Gesperrt

    @Th69 Danke für die Antwort.

    Was kann ich denn tun?

    Also in der CMakeLists von embed-resource änderte ich set(out_f "${PROJECT_BINARY_DIR}/${in_f}.c") zu set(out_f "${PROJECT_BINARY_DIR}/${in_f}.cpp"), damit es wegen der Dateiendung in C++ kompiliert.

    In der Datei embedresource.cpp von embed-resource änderte ich zwei Zeilen, damit vor dem const noch extern steht. ofs << "extern const char _resource_" << sym << "[] = {" << endl; und ofs << "extern const size_t _resource_" << sym << "_len = sizeof(_resource_" << sym << ");";

    Damit die Dateien (mit extern) neu generiert werden, löschte ich die bestehenden zuerst.

    Die Fehlermeldung kam nicht mehr, aber die Ausgabe stimmte nicht ganz. In der Datei stand fragmentshader die Ausgabe war aber fragmentshaderr.

    Als ich dann die CMakeLists wieder von der *.cpp zur *.c Dateiendung änderte, kam wieder die unresolved external symbol Fehlermeldung.


  • Gesperrt

    Diesmal habe ich eine Testvariable in einer Quelldatei test.symbol.c definiert und bin gleich vorgegangen wie in einem vorherigen post.

    #include <iostream>
    
    extern "C" size_t testsymbol;
    
    int main()
    {
    	std::cout << testsymbol << '\n';
    	system("pause");
    }
    

    Das funktionierte. Das Problem ist aber, dass ich die Zeile extern "C" size_t testsymbol; nicht in die main Funktion verschieben kann (error C2598: linkage specification must be at global scope). Daher wird wohl auch das macro von embed-resource nicht funktionieren.

    Edit: Habe das main-file angepasst und dort das macro verändert:

    #include <iostream>
    #include "Resource.h"
    
    #ifdef LOAD_RESOURCE
    #undef LOAD_RESOURCE
    #endif
    
    #define LOAD_RESOURCE(RESOURCE, VARIABLE) \
            extern "C" const char _resource_##RESOURCE[]; \
            extern "C" const size_t _resource_##RESOURCE##_len; \
            Resource VARIABLE = Resource(_resource_##RESOURCE, _resource_##RESOURCE##_len - 1);
    
    LOAD_RESOURCE(frag_glsl, textvar);
    
    int main()
    {
    	std::cout << "test embed resource" << '\n';
    	std::cout << textvar.toString() << '\n';
    
    	system("pause");
    }
    

    Also es funktioniert soweit, bis auf die fehlerhafte Ausgabe von z.B. fragmentshaderr wo eigentlich fragmentshader stehen sollte. Es ist glaube ich immer das letzte Zeichen Zuviel, da embedresource.cpp immer ein Komma setzt.

    Edit: Habe deshalb eine Zeile vom macro im main-file deshalb angepasst mit -1 für len. Resource VARIABLE = Resource(_resource_##RESOURCE, _resource_##RESOURCE##_len - 1);


  • Gesperrt

    Dieser Beitrag wurde gelöscht!

  • Gesperrt

    Dieser Beitrag wurde gelöscht!

Anmelden zum Antworten