LINUX.ORG.RU

использование tmpfile() из библиотеки в основной программе


0

1

Есть маленькая программа:

ядро main.c

#include <stdio.h>

FILE * pFile;

int main()
{
   char mystring [100];
   
   write();
//   pFile = tmpfile();
//   if (pFile == NULL) perror ("Error opening file");
     if ( fgets (mystring , 100 , pFile) != NULL )
       puts (mystring);
   fclose (pFile);
   return 0;
}

динамическая библиотека write.c

#include <stdio.h>

FILE * pFile;

int write ()
{
   char sentence [256];

   printf ("Enter sentence to append: ");
   fgets (sentence,256,stdin);
   pFile = tmpfile();
   fputs (sentence,pFile);
   return 0;
}

write.h:

extern FILE * pFile;

Makefile:

main: main.o libwrite.so
	gcc -o main main.o -L. -lwrite -Wl,-rpath,.

main.o: main.c
	gcc -c main.c

libwrite.so: write.o
	gcc -shared -o libwrite.so write.o
	
write.o: write.c
	gcc -c -fPIC write.c

clean:
	rm -f *.o *.so main

Надо в функцию write ввести поток в tmpfile(), а в ядре им воспользоваться. В данном случае у меня segfault.

★★★★★

Последнее исправление: steemandlinux (всего исправлений: 4)
FILE * pFile;

int write ()
{
...
UVV ★★★★★
()

Тьфу. fclose забыл закомментировать, правда в другой программе он и был в основной программе.

Исправил на текущий вид, теперь программа не вылетает, но main тупо не выводит содержимое pFile.

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от steemandlinux

fclose забыл закомментировать,

Он у тебя всё равно в write() присутствует. Что ты хочешь от файла, если ты его уже закрыл?

UVV ★★★★★
()
Ответ на: комментарий от steemandlinux

А, я не знал, что это библиотечная функция.
Где проверка на NULL и печать errno?

А вообще давай начнём с простого: скажи, что ты хочешь сделать и мы тебе объясним почему ты делаешь это неправильно.

UVV ★★★★★
()
Ответ на: комментарий от UVV

Да вот мне кажется тоже что что-то неправильно делаю.

Есть программка xwd находится в составе x11-apps. Она делает скриншоты в формате xwd. Я её переделал в библиотеку libxwd.so, которая работает без аргументов. Там внутри выполняются 3 записи потока fwrite. Первая запись заголовка, вторая карта цветов и третья сырые данные из иксов image->data. Смысл в том, что мне в мою программу надо получить image->data, я пересмотрел stdio.h и string.h и как сохранить этот поток вне файла я не понял.

В этом потоке мне надо будет перемещаться и дергать нужны данные.

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от steemandlinux

Это видел?

The tmpfile() function opens a unique temporary file in binary read/write (w+b) mode. The file will be automatically deleted when it is closed or the program terminates.

UVV ★★★★★
()
Ответ на: комментарий от arturpub

Я без понятия как копировать потоки. Функции по работе со строками дают только часть данных потока. Объявлен поток как char * data.

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от steemandlinux

char там видимо постольку-поскольку — обычные байты, какой-то нулевой встречается и все. Ты посмотри как там функция записи в файл длину определяет, и столько и забери через malloc+memcpy. Место, где длину можно узнать, будет содержать fwrite/write. Если не разберешься, то запасти куда-нить, наверняка кто подскажет.

arturpub ★★
()
Ответ на: комментарий от arturpub
int Image_Size(XImage *image)
{
    if (image->format != ZPixmap)
      return(image->bytes_per_line * image->height * image->depth);

    return(image->bytes_per_line * image->height);
}

Вроде оно, попробуй так:

size_t size = (size_t)Image_Size(image);
char *datacopy = malloc(size);
memcpy(datacopy, image->data, size);
return datacopy;

arturpub ★★
()
Ответ на: комментарий от arturpub

А дошло теперь, спасибо, а длину потока я знаю, там разрешение*4. А потом мне на нем memchr понадобится.

Буду дальше быдлокодить.

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от arturpub

Что-то тестовый fwrite сегфолтится. А netbeans на fwrite пишет: assign return value to new variable.

__strcmp_sse2_unaligned+0: mov    %edi,%eax
__strcmp_sse2_unaligned+2: xor    %edx,%edx
__strcmp_sse2_unaligned+4: pxor   %xmm7,%xmm7
__strcmp_sse2_unaligned+8: or     %esi,%eax
__strcmp_sse2_unaligned+10: and    $0xfff,%eax
__strcmp_sse2_unaligned+15: cmp    $0xfc0,%eax
__strcmp_sse2_unaligned+20: jg     0x7ffff756ee02 <__strcmp_sse2_unaligned+658>
__strcmp_sse2_unaligned()
__strcmp_sse2_unaligned+26: movdqu (%rdi),%xmm1 - Вот здесь падение
__strcmp_sse2_unaligned+30: movdqu (%rsi),%xmm0
__strcmp_sse2_unaligned+34: pcmpeqb %xmm1,%xmm0
__strcmp_sse2_unaligned+38: pminub %xmm1,%xmm0
__strcmp_sse2_unaligned+42: pxor   %xmm1,%xmm1
__strcmp_sse2_unaligned+46: pcmpeqb %xmm1,%xmm0
__strcmp_sse2_unaligned+50: pmovmskb %xmm0,%eax
__strcmp_sse2_unaligned+54: test   %rax,%rax
__strcmp_sse2_unaligned+57: je     0x7ffff756ebc0 <__strcmp_sse2_unaligned+80>
__strcmp_sse2_unaligned+59: bsf    %rax,%rdx
__strcmp_sse2_unaligned+63: movzbl (%rdi,%rdx,1),%eax
__strcmp_sse2_unaligned+67: movzbl (%rsi,%rdx,1),%edx
__strcmp_sse2_unaligned+71: sub    %edx,%eax
__strcmp_sse2_unaligned+73: retq   
__strcmp_sse2_unaligned+74: nopw   0x0(%rax,%rax,1)

main.c

#include <stdio.h>
#include <stdlib.h>
#include "xwd.h"

/*
 * 
 */
int main ()
{
  FILE * pFile;
  pFile = fopen ("myfile.bin", "wb");
  fwrite (xwdlib() , 1, 8294400, pFile);
  fclose (pFile);
  return 0;
}

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от arturpub

Еще он на поинтеры функций ругается, я расставлял их, ругаться он перестал, но толку никакого, в отладчике тоже самое.

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от steemandlinux

Ну так у тебя вызывается xwdlib, который возвращает 0, а Window_Dump имеет тип int, хотя ты возвращаешь из него char *, который благополучно улетает в воид.

char *
xwdlib(int argc, char **argv)
{
    ...
    char *data = Window_Dump(target_win, out_file);
    ...
    return data;
}

char *
Window_Dump(...

Ну и как минимум

fwrite(xwdlib(0, NULL), ...);

arturpub ★★
()
Последнее исправление: arturpub (всего исправлений: 1)
Ответ на: комментарий от arturpub

main.c:20:3: warning: passing argument 1 of ‘fwrite’ makes pointer from integer without a cast [enabled by default]

fwrite(xwdlib(0, NULL),1, 8294400, pFile);

и сегфолт

Если сделать fwrite((char*)xwdlib(0, NULL), то warning: cast to pointer from integer of different size

и опять сегфолт с той же ошибкой.

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Хэадэр это по-вашенски. У нас у татар есть нужная буква, но вы в нее не можете :)

arturpub ★★
()
Ответ на: комментарий от arturpub

Интересно, вызывает сегфолт xwdlib(0, NULL), потому что простой вызов xwdlib() проходит без ошибок, а fwrite (xwdlib(),...) выдаёт уже другую ошибку.

Прототип в xwd.h:

extern char* xwdlib(int, char**);
steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от steemandlinux

Наверное где-то в Select_Window_Args, по сорцу больше негде. Запусти gdb ./myprogram, потом r, а как повалится — bt. Увидишь, где конкретно повалилось.

arturpub ★★
()
Ответ на: комментарий от arturpub

gcc -g + valgrind сказали что программе не нравится #define INIT_NAME program_name=argv[0]:

Invalid read of size 8
==24191==    at 0x4E3C8B7: xwdlib (xwd.c:153)
==24191==    by 0x4007A6: main (main.c:17)

Ну я теперь понял куда копать.

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от arturpub

Дальше выходит:

==25459== Invalid write of size 8
==25459==    at 0x4E39776: Get_Display_Name (dsimple.c:93)
==25459==    by 0x4E39817: Setup_Display_And_Screen (dsimple.c:130)
==25459==    by 0x4E3C8C5: xwdlib (xwd.c:155)
==25459==    by 0x4007A6: main (main.c:17)

Понятно, надо или полностью удалить все кишки от аргументов или передать нормальные аргументы.

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от arturpub

За fmemopen спасибо, очень пригодилась. А аргументы я так отправил:

char* argroot = "-root"; xwdlib(1, &argroot);

steemandlinux ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.