рдореИрдВ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЦреБрд╢реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬреЛ рдПрдХ рд╕рд╛рдЭрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рд╣реЛ рдЬрд╛рддреА рд╣реИред рдХрдм
рдореИрдВ рдЙрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реЗ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓реЛрдб рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реВрдВ, рдореБрдЭреЗ рдПрдХ рд╕реЗрдЧрдлреЙрд▓реНрдЯ рдорд┐рд▓рддрд╛ рд╣реИред
рдпрд╣ segfault рдХреЗрд╡рд▓ рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рд▓реЛрдб рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХреЙрд▓ рд╣реЛрддреЗ рд╣реИрдВ
рдУрдкрдирдЬреАрдПрд▓ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдЬрд┐рдиреНрд╣реЗрдВ рдЦреБрд╢реА рд╕реЗ рд▓реЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЕрдЧрд░ рдореИрдВ рдЦреБрд╢реА рдХреЗ рдмрдЬрд╛рдп Glew рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ,
рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ, рдХрд╛рд░реНрдпрдХреНрд░рдо рдЕрдкреЗрдХреНрд╖рд╛ рдХреЗ рдЕрдиреБрд░реВрдк рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдореИрдВрдиреЗ рдПрдХ рдЙрдЪрд┐рдд рдиреНрдпреВрдирддрдо рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ рдЬреЛ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдкреБрди: рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред
рдПрдХ glfw- рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рд╡рд┐рдВрдбреЛ рдЦреЛрд▓реА рдЬрд╛рддреА рд╣реИ, рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
lib.so
рд╕рд╛рде dlopen()
рдФрд░ dlsym()
, рдФрд░ рдЙрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред NS
рдлрд╝рдВрдХреНрд╢рди рдмрд╕ рд╕реНрдХреНрд░реАрди рдХреЛ рдиреАрд▓рд╛ рдХрд░ рджреЗрддрд╛ рд╣реИред
рдЬрдм рд╣реИрдкреНрдкреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдХреЙрд▓ рдХреЗ рджреМрд░рд╛рди glClearColor()
рдПрдХ segfault рдлреЗрдВрдХрд╛ рдЬрд╛рддрд╛ рд╣реИред
$ chmod +x build.sh && ./build.sh && ./main
build.sh
рдореЗрдВ рд╣рдЯрд╛ рджреЗрдВ$ .build.sh && ./main
.
тФЬтФАтФА build.sh
тФЬтФАтФА include
тФВ┬а┬а тФЬтФАтФА glad
тФВ┬а┬а тФВ┬а┬а тФФтФАтФА glad.h
тФВ┬а┬а тФФтФАтФА KHR
тФВ┬а┬а тФФтФАтФА khrplatform.h
тФФтФАтФА src
тФЬтФАтФА glad.c
тФЬтФАтФА lib.c
тФФтФАтФА main.c
4 directories, 6 files
#/usr/bin/sh
gcc -std=c99 -Iinclude -Wall -Wextra -Wshadow \
src/main.c src/glad.c -o main \
-ldl -lglfw -lGL
gcc -std=c99 -Iinclude -Wall -Wextra -Wshadow -fpic -shared \
src/lib.c src/glad.c -o lib.so \
-ldl -lglfw -lGL
# building the library with GLEW fixes the problem
#gcc -std=c99 -Wall -Wextra -Wshadow -fpic -shared \
# -DUSE_GLEW \
# src/lib.c -o lib.so \
# -ldl -lglfw -lGL -lGLEW
/*
OpenGL loader generated by glad 0.1.24a0 on Thu May 31 07:06:52 2018.
Language/Generator: C/C++
Specification: gl
APIs: gl=3.3
Profile: compatibility
Extensions:
Loader: True
Local files: False
Omit khrplatform: False
Commandline:
--profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions=""
Online:
http://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3
*/
// ...
#ifdef USE_GLEW
#include <GL/glew.h>
#else
#include <glad/glad.h>
#endif
void draw_blue_screen()
{
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
#include <stdio.h>
#include <stddef.h>
#include <dlfcn.h>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
typedef void (draw_blue_screen_func)(void);
int main(void)
{
if (!glfwInit())
{
fprintf(stderr, "GLFW initialization failed\n");
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(800, 600, "example", NULL, NULL);
if (!window)
{
fprintf(stderr, "GLFW window creation failed\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
{
fprintf(stderr, "glad initialization failed\n");
glfwDestroyWindow(window);
glfwTerminate();
return -1;
}
// Dynamically load a function from lib.so
void *lib_code = dlopen("./lib.so", RTLD_LAZY);
draw_blue_screen_func *draw_blue_screen = (draw_blue_screen_func *) dlsym(lib_code, "draw_blue_screen");
uint64_t frame_number = 0;
while (!glfwWindowShouldClose(window))
{
printf("Frame %" PRIu64 "\n", frame_number);
draw_blue_screen();
glfwSwapBuffers(window);
glfwPollEvents();
frame_number++;
}
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЦреБрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж! рдЗрд╕реЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рдирд╛ рдХрд╛рдлреА рдЕрдЪреНрдЫрд╛ рд░рд╣рд╛ рд╣реИред
рдЕрд░реЗ,
рдЕрдВрдд рдореЗрдВ рдЗрд╕ рдкрд░ рдЧреМрд░ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рдорд┐рд▓рд╛ред рдпрд╣рд╛рдВ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ lib рднреА рдЧреНрд▓реЗрд╡ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ libGL
рдЦрд┐рд▓рд╛рдл рд▓рд┐рдВрдХ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЧреНрд▓реЗрд╡ libGL.so
рд╕реЗ рдкреНрд░рддреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреБрд▓рдирд╛ рдХрд░реЗрдВ:
/tmp/issue151 ┬╗ ldd lib.so # built with USE_GLEW
linux-vdso.so.1 (0x00007fff6434d000)
libdl.so.2 => /lib/libdl.so.2 (0x00007f3a8a97e000)
libGLEW.so.2.1 => /lib/libGLEW.so.2.1 (0x00007f3a8a6d6000)
libc.so.6 => /lib/libc.so.6 (0x00007f3a8a31a000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007f3a8ad84000)
libGL.so.1 => /lib/libGL.so.1 (0x00007f3a8a08f000)
libX11.so.6 => /lib/libX11.so.6 (0x00007f3a89d50000)
libGLX.so.0 => /lib/libGLX.so.0 (0x00007f3a89b1f000)
libXext.so.6 => /lib/libXext.so.6 (0x00007f3a8990d000)
libGLdispatch.so.0 => /lib/libGLdispatch.so.0 (0x00007f3a89657000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007f3a89439000)
libxcb.so.1 => /lib/libxcb.so.1 (0x00007f3a89210000)
libXau.so.6 => /lib/libXau.so.6 (0x00007f3a8900c000)
libXdmcp.so.6 => /lib/libXdmcp.so.6 (0x00007f3a88e06000)
рддрдерд╛
/tmp/issue151 ┬╗ ldd lib.so # built without USE_GLEW (glad)
linux-vdso.so.1 (0x00007ffeab9c2000)
libdl.so.2 => /lib/libdl.so.2 (0x00007efc18716000)
libc.so.6 => /lib/libc.so.6 (0x00007efc1835a000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007efc18b36000)
рдореИрдВрдиреЗ рдЖрдкрдХреА рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рдХреБрдЫ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рд┐рдВрдЯрдл рдЬреЛрдбрд╝реЗ рд╣реИрдВ:
printf("[lib] glClearColor: %p@%p\n", glClearColor, &glClearColor);
printf("[lib] glClear: %p@%p\n", glClear, &glClear);
printf("[lib] glFramebufferTexture: %p@%p\n", glFramebufferTexture, &glFramebufferTexture);
#ifdef USE_GLEW
printf("[glew] glClearColor: %p@%p\n", __glewClearColorx, &__glewClearColorx);
#endif
[glad] glClearColor: 0x7fb491c2d720<strong i="17">@0x55de31f07428</strong>
[glad] glClear: 0x7fb491c2d600<strong i="18">@0x55de31f06af0</strong>
[dlsym] glClearColor: 0x7fb4939fb720<strong i="19">@0x7fff96d92858</strong>
[dlsym] glClear: 0x7fb4939fb600<strong i="20">@0x7fff96d92850</strong>
Frame 0
[lib] glClearColor: 0x7fb4939fb720<strong i="21">@0x7fb4939fb720</strong>
[lib] glClear: 0x7fb4939fb600<strong i="22">@0x7fb4939fb600</strong>
[lib] glFramebufferTexture: (nil)<strong i="23">@0x7fb48db18050</strong>
[glew] glClearColor: (nil)<strong i="24">@0x7fb48db13db8</strong>
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ glFramebufferTexture
nil
рд╕рд╛рде-рд╕рд╛рде glClearColor
рд▓рд┐рдП рдЖрдВрддрд░рд┐рдХ рдЪрдордХ рдкреНрд░рддреАрдХ рд╣реИред lib.c
рдУрдкрдирдЬреАрдПрд▓ 1.0 рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреБрдЫ рднреА рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдХреНрд╖рдг рдХреЛ рддреЛрдбрд╝ рджреЗрдЧрд╛ред
рдЖрдк рдЕрдкрдиреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдУрдкрдирдЬреАрдПрд▓ (рдЦреБрд╢ рдпрд╛ рдЪрдордХреАрд▓рд╛) рд╢реБрд░реВ рдХрд░рдХреЗ рдЗрд╕рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
void lib_init()
{
#ifndef USE_GLEW
gladLoadGL();
#endif
}
// Dynamically load a function from lib.so
void *lib_code = dlopen("./lib.so", RTLD_LAZY);
draw_blue_screen_func *draw_blue_screen = (draw_blue_screen_func *) dlsym(lib_code, "draw_blue_screen");
((void(*)()) dlsym(lib_code, "lib_init"))();
рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдХреНрдпрд╛ рдЖрдк рдХреБрдЫ рддрд░рдХреАрдмреЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдХреЗ рдкрд╣рд▓реЗ рд╕реЗ рд▓реЛрдб рдХрд┐рдП рдЧрдП рдкреНрд░рддреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рдЖрдк рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рджреЛрдиреЛрдВ рдлрд╛рдЗрд▓реЛрдВ рдореЗрдВ рдПрдХ рдЧрддрд┐рд╢реАрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд░реВрдк рдореЗрдВ рдЦреБрд╢реА / рдЪрдордХ рдХреЗ рдЦрд┐рд▓рд╛рдл рд▓рд┐рдВрдХ рдХрд░рддреЗ рд╣реИрдВ ( main.c
рдФрд░ lib.c
) рд▓реЗрдХрд┐рди рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдореИрдВ POSIX рдФрд░ рди рд╣реА рдЧрддрд┐рд╢реАрд▓ рд▓рд┐рдВрдХрд┐рдВрдЧ рд╕реЗ рдкрд░реНрдпрд╛рдкреНрдд рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВред
рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдЗрд╕рд╕реЗ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рдорд┐рд▓ рдЧрдпрд╛ред
рдЗрд╕ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ gladLoadGL()
рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░ рдХреНрдпрд╛ рдЦреБрд╢реА рд╣реЛ рд░рд╣реА рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рд╕реАрдЦрдирд╛ рдФрд░ рд╕реАрдЦрдирд╛ рд╕рдорд╛рдкреНрдд рдХрд░ рджрд┐рдпрд╛ред рдЕрдм рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддреАрдХреЛрдВ рдХреЛ рд╕рд╛рдЭрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рддрдХ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдкрд╣реБрдБрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЦреБрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж! рдЗрд╕реЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рдирд╛ рдХрд╛рдлреА рдЕрдЪреНрдЫрд╛ рд░рд╣рд╛ рд╣реИред