Sign in to follow this  
Followers 0

read file content

24 posts in this topic

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

Share this post


Link to post
Share on other sites



Posted

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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.

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

Posted

Almost. Buffer should only be a single layer pointer.

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

Posted

Yes.

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

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

Posted

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Posted

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

Share this post


Link to post
Share on other sites

Posted

If is so obvious, enlighten me. :unsure:

Share this post


Link to post
Share on other sites

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.

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