Jump to content



Photo

read file content


  • Please log in to reply
23 replies to this topic

#1 Andreik

Andreik

    Bishop

  • Active Members
  • PipPipPipPipPipPip
  • 2,503 posts

Posted 16 May 2011 - 03:56 PM

Hi guys,
I want to create a dll with VC++ 2008 Express and then use it in autoit scripts but I encounter some troubles.

Dll Code
#include <stdio.h> #include <stdlib.h> extern "C"  __declspec(dllexport) size_t FileOpen(char *filename) {     FILE * pFile;     long lSize;     char * buffer;     size_t result;     pFile=fopen(filename,"rb");     fseek(pFile,0,SEEK_END);     lSize=ftell(pFile);     rewind(pFile);     buffer = (char*) malloc (sizeof(char)*lSize);     result = fread (buffer,1,lSize,pFile);     fclose (pFile);     free (buffer);     return result; }


When I compile this dll I got one warning but no errors. If I try to use this function from AutoIt script will crash.
#include <Array.au3> $DLL = DllOpen("File.dll") $RESULT = DllCall($DLL,"int:cdecl","FileOpen","str","Test1.dat") DllClose($DLL) _ArrayDisplay($RESULT)


Anyone know what I make wrong?

Edited by Andreik, 16 May 2011 - 05:35 PM.

When the words fail... music speaks







#2 Richard Robertson

Richard Robertson

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 9,716 posts

Posted 16 May 2011 - 04:24 PM

Why did you mark it returning string when it actually returns an integer?

#3 Andreik

Andreik

    Bishop

  • Active Members
  • PipPipPipPipPipPip
  • 2,503 posts

Posted 16 May 2011 - 04:49 PM

Hmm seems I misunderstood size_t type but you're right work well if I call the function as int:cdecl but the result after dllcall looks like that:

$Result[0] = 14 $Result[1] = "Test1.dat"

Text in Test1.dat is "this is a test" 14 chars, so there's something in $Result[0] but I don't know how to get it. Or any way to convert size_t to char?

Edited by Andreik, 16 May 2011 - 04:50 PM.

When the words fail... music speaks

#4 Valik

Valik

    Former developer.

  • Active Members
  • PipPipPipPipPipPip
  • 18,879 posts

Posted 16 May 2011 - 04:55 PM

You need to stop and go learn C/C++ before you try writing DLLs. You are clearly missing some rather fundamental pieces of information.

#5 Andreik

Andreik

    Bishop

  • Active Members
  • PipPipPipPipPipPip
  • 2,503 posts

Posted 16 May 2011 - 05:01 PM

I can learn by practicing, would be a differece if I write simple codes or DLLs? Actually I am not very interesed about C, I just try to make some speedy functions for some AutoIt scripts.
When the words fail... music speaks

#6 Valik

Valik

    Former developer.

  • Active Members
  • PipPipPipPipPipPip
  • 18,879 posts

Posted 16 May 2011 - 05:04 PM

And once again the advice of a person who is self-taught and has 8+ years of experience and helped design the language you are using is ignored because clearly and demonstrably you know more than I do.

#7 Andreik

Andreik

    Bishop

  • Active Members
  • PipPipPipPipPipPip
  • 2,503 posts

Posted 16 May 2011 - 05:06 PM

Don't put words in my mouth, I didn't said I am more experienced then you. If you wanna help in any way give me a tutorial.

EDIT: Finally I figured out
#include <stdio.h> #include <stdlib.h> extern "C"  __declspec(dllexport) char *ReadFile(char *filename) {     FILE * pFile;     long lSize;     char * buffer;     size_t result;     pFile=fopen(filename,"rb");     fseek(pFile,0,SEEK_END);     lSize=ftell(pFile);     rewind(pFile);     buffer = (char*) malloc (sizeof(char)*lSize);     result = fread (buffer,1,lSize,pFile);     fclose (pFile);     return buffer; }

$RESULT = DllCall("FileOpen.dll","str:cdecl","ReadFile","str","test.txt") MsgBox(0,"",RESULT[0])

Edited by Andreik, 16 May 2011 - 06:36 PM.

When the words fail... music speaks

#8 Richard Robertson

Richard Robertson

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 9,716 posts

Posted 16 May 2011 - 06:36 PM

You're still not doing it right. You should never return a pointer to an allocated resource like that. If you're going to return a string, then it should be a parameter that you modify, and you return the number of characters, just like fread.

#9 Andreik

Andreik

    Bishop

  • Active Members
  • PipPipPipPipPipPip
  • 2,503 posts

Posted 16 May 2011 - 06:45 PM

Ok, let's see now:
#include <stdio.h> #include <stdlib.h> extern "C"  __declspec(dllexport) size_t BitmapOpen(char *filename, char **buffer) {     FILE * pFile;     long lSize;     size_t result;     pFile=fopen(filename,"rb");     fseek(pFile,0,SEEK_END);     lSize=ftell(pFile);     rewind(pFile);     result = fread (buffer,1,lSize,pFile);     fclose (pFile);     return result; }

Looks better?

Edited by Andreik, 16 May 2011 - 06:46 PM.

When the words fail... music speaks

#10 Richard Robertson

Richard Robertson

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 9,716 posts

Posted 16 May 2011 - 08:23 PM

Almost. Buffer should only be a single layer pointer.

#11 Andreik

Andreik

    Bishop

  • Active Members
  • PipPipPipPipPipPip
  • 2,503 posts

Posted 16 May 2011 - 08:31 PM

And I think to call this from AutoIt I need to create a stuct and pass the pointer of struct as buffer parameter, right?
When the words fail... music speaks

#12 Richard Robertson

Richard Robertson

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 9,716 posts

Posted 17 May 2011 - 01:36 AM

Yes.

#13 Andreik

Andreik

    Bishop

  • Active Members
  • PipPipPipPipPipPip
  • 2,503 posts

Posted 17 May 2011 - 02:44 PM

Thanks man, understood until now. One more question: can I know in a smart way how big should be the buffer to can create a properly struct?
When the words fail... music speaks

#14 Richard Robertson

Richard Robertson

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 9,716 posts

Posted 17 May 2011 - 02:59 PM

There are three methodologies to buffer sizes.

1. Allocate a buffer that is large enough it could contain any possible data you will read. (Most typical)
2. Make a function call to see how much you need, then allocate it.
3. Use a dynamic system that allocates more memory as more is put into it. (Most expensive)

#15 Andreik

Andreik

    Bishop

  • Active Members
  • PipPipPipPipPipPip
  • 2,503 posts

Posted 17 May 2011 - 08:07 PM

No.2 sounds pretty good. I will try this one. Thanks a lot man.
When the words fail... music speaks

#16 Andreik

Andreik

    Bishop

  • Active Members
  • PipPipPipPipPipPip
  • 2,503 posts

Posted 18 May 2011 - 04:08 PM

Richard, I have just one more question. Am I missing something, "rb" doesn't mean read binary, why my result isn't binary?

Bitmap.dll
Plain Text         
extern "C"  __declspec(dllexport) size_t BitmapOpen(char *filename, char *buffer) {     FILE * pFile;     long lSize;     size_t result;     pFile=fopen(filename,"rb");     fseek(pFile,0,SEEK_END);     lSize=ftell(pFile);     rewind(pFile);     result = fread (buffer,1,lSize,pFile);     fclose (pFile);     return result; } extern "C"  __declspec(dllexport) long BitmapBuffer(char *filename) {     FILE * pFile;     long lSize;     pFile=fopen(filename,"rb");     fseek(pFile,0,SEEK_END);     lSize=ftell(pFile);     fclose (pFile);     return lSize; }


Bitmap.au3
Plain Text         
$BMP = BitmapOpen("test.bmp") If @error Then     MsgBox(0,"Error",@error) Else     MsgBox(0,"",$BMP) EndIf Func BitmapOpen($PATH)     Local $BUFFER_SIZE, $BITMAP, $STRUCT     Local $BUFFER_SIZE = DllCall("Bitmap.dll","long:cdecl","BitmapBuffer","str",$PATH)     If @error Then         SetError(1)     Else         $STRUCT = DllStructCreate("char [" & $BUFFER_SIZE[0] & "]")         $BITMAP = DllCall("Bitmap.dll","int:cdecl","BitmapOpen","str",$PATH,"ptr",DllStructGetPtr($STRUCT))         If @error Then             $STRUCT = 0             SetError(2)         Else             Return DllStructGetData($STRUCT,1)         EndIf     EndIf EndFunc

When the words fail... music speaks

#17 Richard Robertson

Richard Robertson

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 9,716 posts

Posted 19 May 2011 - 04:44 AM

You've provided me with no error context. I have no idea what your problem is.

#18 trancexx

trancexx

    Hm, I really shouldn't.

  • Active Members
  • PipPipPipPipPipPip
  • 5,243 posts

Posted 19 May 2011 - 05:03 AM

It's too obvious. Doesn't even deserve a comment.

eMyvnE


#19 Andreik

Andreik

    Bishop

  • Active Members
  • PipPipPipPipPipPip
  • 2,503 posts

Posted 19 May 2011 - 08:31 AM

If is so obvious, enlighten me. :unsure:
When the words fail... music speaks

#20 trancexx

trancexx

    Hm, I really shouldn't.

  • Active Members
  • PipPipPipPipPipPip
  • 5,243 posts

Posted 19 May 2011 - 03:40 PM

If I wanted to do that I would have already.
You wrote the code, right? If you don't know why something happens then there could be a problem with you and your logic or knowledge and overall understanding of the programming process.
Once again, it's too obvious.

eMyvnE





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users