Sign in to follow this  
Followers 0

read file content

24 posts in this topic

#1 ·  Posted (edited)

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

When the words fail... music speaks

Share this post


Link to post
Share on other sites



#2 ·  Posted

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

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

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

When the words fail... music speaks

Share this post


Link to post
Share on other sites

#4 ·  Posted

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

Share this post


Link to post
Share on other sites

#5 ·  Posted

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

Share this post


Link to post
Share on other sites

#6 ·  Posted

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.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

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

When the words fail... music speaks

Share this post


Link to post
Share on other sites

#8 ·  Posted

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.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

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

When the words fail... music speaks

Share this post


Link to post
Share on other sites

#10 ·  Posted

Almost. Buffer should only be a single layer pointer.

Share this post


Link to post
Share on other sites

#11 ·  Posted

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

Share this post


Link to post
Share on other sites

#12 ·  Posted

Yes.

Share this post


Link to post
Share on other sites

#13 ·  Posted

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

Share this post


Link to post
Share on other sites

#14 ·  Posted

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)

Share this post


Link to post
Share on other sites

#15 ·  Posted

No.2 sounds pretty good. I will try this one. Thanks a lot man.


When the words fail... music speaks

Share this post


Link to post
Share on other sites

#16 ·  Posted

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

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

$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

Share this post


Link to post
Share on other sites

#17 ·  Posted

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

Share this post


Link to post
Share on other sites

#18 ·  Posted

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


 

.

eMyvnE

Share this post


Link to post
Share on other sites

#19 ·  Posted

If is so obvious, enlighten me. :unsure:


When the words fail... music speaks

Share this post


Link to post
Share on other sites

#20 ·  Posted

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0