How to extern SDL_Surface array in C? - c

I want to extern a SDL_Surface array from one function (load_level) to another (initialize_balls). I have to say that the SDL_Surface (brickim) is a dynamic pointer-struct which is defined inside of load_level function via malloc function and declared as SDL_Surface **brickim as well. I got a segmentation fault when I try to access brickim[0]->w in the initialize_balls function but not in the load_level function. This is the piece of code I hope you could help me to fix.
file1.c
#include <stdio.h>
#include <SDL.h>
SDL_Surface **brickim; /*as global*/
SDL_Surface* load_map(char *map_name , int tran );
void load_level(int stage){
int n;
SDL_Surface **brickim=( SDL_Surface **)malloc(sizeof(SDL_Surface)*input.N);
for (n=0;n < input.N;n++){
**brickim[n]=load_map("brick1.bmp",1); /*load SDL_Surfaces*/**
printf("%d\n",brickim[n]->w); /***access succesfully (returns 100 N times)***/
}
...
}}
SDL_Surface* load_map(char *map_name , int tran ){
SDL_Surface *temp,*map;
Uint32 colorkey;
printf("Loading bit map %s %d...\n",map_name,tran);
temp = SDL_LoadBMP(map_name);
if (temp == NULL){
printf("Unable to load bitmap: %s\n", SDL_GetError());
SDL_FreeSurface(temp);
exit(0);
}else{
map = SDL_DisplayFormat(temp);
colorkey = SDL_MapRGB( map -> format, 132, 0, 12);
if ( tran==1 ) SDL_SetColorKey( map, SDL_SRCCOLORKEY, colorkey );
SDL_FreeSurface(temp);
}
return map;
}
file2.c
#include <SDL.h>
#include <stdlib.h>
#include <stdio.h>
extern SDL_Surface **brickim;/*brings brickim to this function*/
void initialize_balls()
{
printf("Into initialization :)\n ");
printf("%d \n",brickim[0]->w); /***returns segmentation fault***/
}
$./kuranes
Loading bit map brick1.bmp 1...
level image:) 100 (x10 times)
Into initialization :)
Violación de segmento (`core' generado)
Everything was running ok when I used a single SDL_Surface compiled with gcc but I need to do it dynamically. I think something very basic is missing.

Your problem seems to be here. You declare a global brickim, this will be what the extern declaration finds. You then, in load_level, declare a local brickim variable. You can declare a variable with the same name in different scopes, but the global brickim will not be used within load_level, the local one will. Therefore, while you do malloc into the local brickim, you don't ever assign into the global brickim - and therefore if you access it via extern, it will be NULL and you'll segfault.
SDL_Surface **brickim; /*as global*/
SDL_Surface* load_map(char *map_name , int tran );
void load_level(int stage){
int n;
SDL_Surface **brickim=( SDL_Surface **)malloc(sizeof(SDL_Surface)*input.N);
for (n=0;n < input.N;n++){
**brickim[n]=load_map("brick1.bmp",1); /*load SDL_Surfaces*/**
printf("%d\n",brickim[n]->w); /***access succesfully (returns 100 N times)***/
}
...
}}
edit: you might want to check that whole allocation in general. I'm not familiar with the SDL_Surface struct, but i assume it's not a pointer type (it's a generic struct). Your allocation is actually allocating N structures, but you're casting as if you're allocating N pointers to SDL_Surface structures. Don't cast malloc.
If you want N SDL_Surface structures, you only need to have:
SDL_Surface * brickim = malloc(sizeof(SDL_Surface) * N)
If you want N pointers to SDL_Surface structures, you would need:
SDL_Surface ** brickim = malloc(sizeof(SDL_Surface *) * N)
for( i = 0; i < N; i++){
// you've only allocated an array of pointers so far, you now need
// allocate N structures
brickim[0] = malloc(sizeof(SDL_Surface));
}

Related

C pointer casting to and from Go

I'm writing an app for the windows platform using FFmpeg and it's golang wrapper goav, but I'm having trouble understanding how to pass the C pointers between C and Go.
I've stripped out all the relevant parts of the C code, the wrapper and my code, shown below:
C code - libavutil/frame.h
#include <stdint.h>
typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
uint8_t *data[AV_NUM_DATA_POINTERS];
}
Go goav wrapper
package avutil
/*
#cgo pkg-config: libavutil
#include <libavutil/frame.h>
#include <stdlib.h>
// C code I added:
#include <stdio.h>
void SaveFrame(const char* location, uint8_t *data, int width, int height) {
FILE *pFile;
int y;
// Open file
pFile=fopen(location, "wb");
if(pFile==NULL)
return;
// Write header
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
// Write pixel data
for(y=0; y<height; y++)
fwrite(data+y*width, 1, width*3, pFile);
// Close file
fclose(pFile);
}
*/
import "C"
import (
"unsafe"
)
type Frame C.struct_AVFrame
func Data(f *Frame) *uint8 {
// i think this is the function thats not working?
return (*uint8)(unsafe.Pointer((*C.uint8_t)(unsafe.Pointer(&f.data))))
}
func SaveFrame(location string, data *uint8, width int, height int) {
C.SaveFrame(C.CString(location), unsafe.Pointer(data), C.int(width), C.int(height))
}
My Go code
package main
import "github.com/giorgisio/goav/avutil"
func main() {
var frame *avutil.Frame
var data *uint8
//... initialize frame
data = avutil.Data(frame)
avutil.SaveFrame("frame0.ppm", data, 1920, 1080)
}
When I try to save the frame, the resulting image is garbled because the pointer is wrong, how do i fix this?
The data field of the AVFrame struct is an array of 8 pointers.
That is, it's a contiguous chunk of memory containing 8 slots
adjacent to each other—each holding a pointer (to a value of type uint8_t).
IOW, the declaration
uint8_t *data[AV_NUM_DATA_POINTERS];
is better interpreted as
uint8_t* data[AV_NUM_DATA_POINTERS];
and in Go, you'd declare it something like
var data [AV_NUM_DATA_POINTERS]*uint8_t
Now your SaveFrame function declares its data arguments to
be of type uint8_t*. That is okay to pass the address of the
data array of an AVFrame struct as that argument, but more idiomatic
would be to pass the address of its zeroth element—something like
func Data(frame *Frame) *uint8 {
return (*uint8)(unsafe.Pointer(&frame.data[0]))
}

I keep getting an error when I try to define an element of a struct

I am teaching myself C. I followed a tutorial and got an image to move around on the screen. Now I am trying to do it on my own and understand how to modularize my code and know whats going on with it.
I built a struct to get player coordinates and called it into my game_loop.h file. but it don't let me set variables from the struct. I tried to include just the important bits to keep it concise. Let me know if I need to post the whole code.
What am I doing wrong.
//includes
#include "game_loop.h"
//main body
int main( int argc, char *argv[])
{
//TODO make game menu and link it here
//TODO make game loop and put it here
initSDL();
renderGame();
handleEvent();
//make game cleanup and put it her
destroySDL();
return 0;
}
int header file game_loop.h -->
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "player.h"
#define pSIZE 64
#define wWIDTH 1280
#define wHEIGHT 720
//variables for starting SDL
SDL_Event event;
SDL_Window *window = NULL;
SDL_Renderer *render = NULL;
SDL_Surface *bgSurface = NULL;
SDL_Texture *bgTexture = NULL;
SDL_Surface *pSurface = NULL;
SDL_Texture *pTexture = NULL;
int flags = 0; //window flags may need to change in the future
struct Player player;
player.x = 600;
player.y = 300;
void initSDL()
{
//initializing SDL
if(SDL_Init(SDL_INIT_VIDEO)!= 0)
{
printf("ERROR starting SDL: %s\n", SDL_GetError());
}else{printf("Starting SDL: Successful.\n");}
in a player.h file -->
struct Player{
int x;
int y;
};
You have lines of executable code outside of a function:
Player player;
player.x = 600;
player.y = 300;
The first line defines a variable. That is OK. The next two lines are not, as they are statements.
You need to initialize the struct at the time it is defined. You can do it as follows:
Player player = { 600, 300 };
Also, it's not a good idea to define variables in header files. If a header is used in multiple source files, you'll end up with errors due to multiple definitions.
In your header file, variables should be declared as extern without an initializer:
extern Player player;
Then you would put the definition with the initializer in exactly one source file.
Similarly for functions, put a declaration of the function in the header, and the definition of the function in one source file.

How to use MagickGetImageHistogram of ImageMagick C API

I have been using ImageMagick's C API using LuaJIT and FFI library and magick lua module for this. Now I want to use MagickGetImageHistogram method. So when it comes to pass an argument check my below code.
***image.lua***
local len = ffi.new("size_t[?]", 5)
local t = handle_result(self, lib.MagickGetImageHistogram(self.wand, len))
***lib.lua***
local ffi = require("ffi")
local lib
ffi.cdef([[ typedef void MagickWand;
typedef void PixelWand;
typedef int MagickBooleanType;
typedef int ExceptionType;
typedef int ssize_t;
typedef int CompositeOperator;
typedef int GravityType;
typedef int OrientationType;
typedef int InterlaceType;
typedef char DistortMethod[];
void MagickWandGenesis();
MagickWand* NewMagickWand();
PixelWand **MagickGetImageHistogram(MagickWand *wand, size_t *number_colors);
So I'm sure that my first argument is correct but not sure about second one.
And it returns the image histogram as an array of PixelWand wands. So how do I convert it to LuaJIT structure?
I'm not sure about the lua parts of the question, but the expected behavior MagickGetImageHistogram is as follows.
Method will return an array of pixel pointers.
Argument size_t *number_colors will be updated with the count of pixels in array.
Each pixel in array will need to invoke method PixelGetColorCount to retrieve the sum of pixels used by image.
Here's a quick example in C.
#include <stdio.h>
#include <wand/MagickWand.h>
int main(int argc, const char * argv[]) {
// Prototype vars
MagickWand * wand;
PixelWand ** histogram;
size_t histogram_count = 0;
// Boot environment.
MagickWandGenesis();
// Allocate & read image
wand = NewMagickWand();
MagickReadImage(wand, "rose:");
// Get Histogram as array of pixels
histogram = MagickGetImageHistogram(wand, &histogram_count);
// Iterate over each pixel & dump info.
for (int i = 0; i < histogram_count; ++i)
{
printf("%s => %zu\n",
PixelGetColorAsString(histogram[i]),
PixelGetColorCount(histogram[i]));
}
// Clean-up
histogram = DestroyPixelWands(histogram, histogram_count);
wand = DestroyMagickWand(wand);
MagickWandTerminus();
return 0;
}
This example will output the expected text...
// ...
srgb(48,45,43) => 1
srgb(50,45,42) => 2
srgb(50,44,43) => 5
srgb(51,45,43) => 1
// ...
So I would guess your lua script would look something like..
***image.lua***
local tlen = ffi.new("size_t[1]")
local t = lib.MagickGetImageHistogram(self.wand, tlen)
for i=0,tlen[0] do
handle_new_pixel(self, t[i], lib.PixelGetColorCount(t[i]))
end

glfw - is a realloc inside key_callback possible?

I am trying to make a drawing in openGL using glfw, the problem i'm facing is that to save the various coordinates of the points (i can't know their value or how many there will be in advance) i need to realloc a pointer to get more space to save them.
I need to realloc the pointer only when i press a button, hence i thought it made sense for the realloc to be in the key_callback function.
The problem is that, obviously, int *pointer isn't in the scope of key_callbackso i can't realloc it directly there and i can't pass the int * to key_callback since it's a glfw fucntion that has specific arguments that i can't change.
My question is, should i declare int *pointer = malloc outside of main (globally) so that it's visible from both main and key_callback, increase a global variable inside key_callback and do something like if (new_variable_value != old_variable_value){realloc} inside main or there exist a third alternative that i didn't think of?
This is a skeleton of the code i have now: (obviously it won't work for many reasons, it's just to give you an idea of what i want to do)
key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
// do stuff
// realloc pointer
}
int main(void) {
int *pointer = malloc(sizeof(int));
if (!pointer){
free(pointer);
exit(EXIT_FAILURE);
}
GLFWwindow *window;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
window = glfwCreateWindow(1280, 720, "Example", NULL, NULL);
if (!window) {
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
while (!glfwWindowShouldClose(window)) {
//draw stuff
glfwSwapBuffers(window);
glfwPollEvents();
}
free(pointer);
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
User pointer:
Each window has a user pointer that can be set with glfwSetWindowUserPointer and fetched with glfwGetWindowUserPointer. This can be used for any purpose you need and will not be modified by GLFW throughout the life-time of the window.
The initial value of the pointer is NULL.
Declare pointer as a global variable. This is the simplest possible fix.
You will need to initialize the pointer with malloc() within main() -- variables declared in the global scope can only be initialized to constant values, not function calls.

External Functions and Parameter Size Limitation (C)

I am very much stuck in the following issue. Any help is very much appreciated!
Basically I have a program wich contains an array of structs and I am getting a segmentation error when I call an external function. The error only happens when I have more than 170 items on the array being passed.
Nothing on the function is processed. The program stops exactly when accessing the function.
Is there a limit for the size of the parameters that are passed to external functions?
Main.c
struct ratingObj {
int uid;
int mid;
double rating;
};
void *FunctionLib; /* Handle to shared lib file */
void (*Function)(); /* Pointer to loaded routine */
const char *dlError; /* Pointer to error string */
int main( int argc, char * argv[]){
// ... some code ...
asprintf(&query, "select mid, rating "
"from %s "
"where uid=%d "
"order by rand()", itable, uid);
if (mysql_query(conn2, query)) {
fprintf(stderr, "%s\n", mysql_error(conn2));
exit(1);
}
res2 = mysql_store_result(conn2);
int movieCount = mysql_num_rows(res2);
// withhold is a variable that defines a percentage of the entries
// to be used for calculations (generally 20%)
int listSize = round((movieCount * ((double)withhold/100)));
struct ratingObj moviesToRate[listSize];
int mvCount = 0;
int count =0;
while ((row2 = mysql_fetch_row(res2)) != NULL){
if(count<(movieCount-listSize)){
// adds to another table
}else{
moviesToRate[mvCount].uid = uid;
moviesToRate[mvCount].mid = atoi(row2[0]);
moviesToRate[mvCount].rating = 0.0;
mvCount++;
}
count++;
}
// ... more code ...
FunctionLib = dlopen("library.so", RTLD_LAZY);
dlError = dlerror();
if( dlError ) exit(1);
Function = dlsym( FunctionLib, "getResults");
dlError = dlerror();
(*Function)( moviesToRate, listSize );
// .. more code
}
library.c
struct ratingObj {
int uid;
int mid;
double rating;
};
typedef struct ratingObj ratingObj;
void getResults(struct ratingObj *moviesToRate, int listSize);
void getResults(struct ratingObj *moviesToRate, int listSize){
// ... more code
}
You are likely blowing up the stack. Move the array to outside of the function, i.e. from auto to static land.
Another option is that the // ... more code - array gets populated... part is corrupting the stack.
Edit 0:
After you posted more code - you are using C99 variable sized array on the stack - Bad IdeaTM. Think what happens when your data set grows to thousands, or millions, of records. Switch to dynamic memory allocation, see malloc(3).
You don't show us what listsize is, but I suppose it is a variable and not a constant.
What you are using are variable length arrays, VLA. These are a bit dangerous if they are too large since they usually allocated on the stack.
To work around that you can allocate such a beast dynamically
struct ratingObj (*movies)[listSize] = malloc(sizeof(*movies));
// ...
free(movies);
You'd then have in mind though that movies then is a pointer to array, so you have to reference with one * more than before.
Another, more classical C version would be
struct ratingObj * movies = malloc(sizeof(*movies)*listsize);
// ...
free(movies);

Resources