Sign in to follow this  
Followers 0
korifg

Unsuccessful DLLCALL

17 posts in this topic

Hi!

I need to make some low level routines what i can call from Autoit.

I was going to make a DLL library with my routines and I call them from Autoit.

I tried a different methodes but they did not work.

At last a made a very simple case - still unsuccessfull.

What can be the problem?

Here it is:

Autoit code:

Dim $result[50]
$dll = DllOpen("ClassLibrary1.dll")

MsgBox ( 0, "Error Code, ClassLibrary1.dll: ", @error )

$result = DllCall($dll, "int", "Return5", "int", 0 )

MsgBox ( 0, "Error Code", @error )
msgbox(0, "Res0", $result[0])  
msgbox(0, "Res1", $result[1])

My DLL source code:

using System;
using System.Collections.Generic;
using System.Text;

namespace ClassLibrary1
{
    public class Class1
    {
        public int Return5(int bejovo)
        {
            return 5;
        }   

    }
}

Share this post


Link to post
Share on other sites



Well, given that you didn't tell anybody what language you're using, I'm going to guess it's C# but it could be managed C++ since I'm not familiar with the extensions to C++ which make it .NET compatible. That being said, do you know how to write a Dll in a .NET language which exports functions? I highly doubt the basic sample you've provided is exporting the function. I would look at the documentation for whatever .NET language you are using and find out how to create a Dll that exports symbols.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I use Visual C# 2005.

When I created this function i had selected Class Library. I should or should not be eonugh.

I use C# as i got the routines in that language. Those routines part of a program.

So I planned to strip the surplus from the source code. Make the necessary interface. And voile, use it.

Edited by korifg

Share this post


Link to post
Share on other sites

You're asking a non-AutoIt related question. You need to read MSDN about how to create Dlls exporting function symbols in C#.

Share this post


Link to post
Share on other sites

You're asking a non-AutoIt related question. You need to read MSDN about how to create Dlls exporting function symbols in C#.

Well I did what you suggested.

I made a perfect DLL now, in this case i used Visual C++ 2005.

The DLLCALL still does not work.

Please do not say just "It is not Autoit problem"

You should better tell me that what requirements Autoit has towards a DLL.

What limitations DLLCALL function has, etc.

Just briefly: an in depth documentation of DLLCALL function.

It is a perfect DLL library, because I carefully followed the steps described in MSDN.

see: http://msdn2.microsoft.com/en-us/library/ms235636.aspx

Dim $result[50]
$dll = DllOpen("MathFuncsDll.dll")
$result = DllCall($dll, "int", "Add", "int", 5, "int", 6 )

// MathFuncsDll.cpp
// compile with: /EHsc /LD

#include "MathFuncsDll.h"

#include <stdexcept>

using namespace std;

namespace MathFuncs
{
    int MyMathFuncs::Add(int a, int b)
    {
        return a + b;
    }
}

// MathFuncsDll.h

namespace MathFuncs
{
    class MyMathFuncs
    {
    public:
        // Returns a + b
        static __declspec(dllexport) int Add(int a, int b);

    };
}

Share this post


Link to post
Share on other sites

I did not put the last 2 line in the example, now i do:

Dim $result[50]
$dll = DllOpen("MathFuncsDll.dll")

$result = DllCall($dll, "int", "Add", "int", 5, "int", 6 )
MsgBox ( 0, "Error Code", @error )
msgbox(0, "Res0", $result[0])

What will happen when I run the code:

The @error will be 1. Means the DLLCALLl was unsuccessful.

So 1st we should fix somehow that DLLCALL.

(I have checked before - the Dllopen function is successful.

Also I got an error message on displaying $result[0] in a message box, because the unsucessful DLLCALL function.)

Share this post


Link to post
Share on other sites

BTW, does andybody has a working example of DLLCALL, where the DLL was not provided by MS but created ?

May I have the source code of that library?

Share this post


Link to post
Share on other sites

First problem I see is you're not exporting the symbol using 'extern "C"' so there's a good chance the symbol being exported has a mangled name. Second, I see no point in the namespace and the class. These may or may not be adding more qualifiers to the exported symbol. Third, to be totally correct, the function needs to use either __stdcall or WINAPI for it's calling convention (They are the same thing). And lastly, you should probably just use a module definition file to export the symbol instead of declspec(dllexport). It makes things much easier as you don't have to worry about name mangling and the like (Which means 'extern "C"' which you are missing isn't necessary).

As to answer your last question: Search the forum. There are a couple "Add" functions written by users to test out their ability to write DllCall()-suitable Dlls.

Share this post


Link to post
Share on other sites

You should better tell me that what requirements Autoit has towards a DLL.

First problem I see is you're not exporting the symbol using 'extern "C"' so there's a good chance the symbol being exported has a mangled name. Second, I see no point in the namespace and the class. These may or may not be adding more qualifiers to the exported symbol. Third, to be totally correct, the function needs to use either __stdcall or WINAPI for it's calling convention (They are the same thing). And lastly, you should probably just use a module definition file to export the symbol instead of declspec(dllexport). It makes things much easier as you don't have to worry about name mangling and the like (Which means 'extern "C"' which you are missing isn't necessary).

As to answer your last question: Search the forum. There are a couple "Add" functions written by users to test out their ability to write DllCall()-suitable Dlls.

awww. i was all giddy scrolling down to find valik's response to that line, absolutely sure that i was going to be laughing out loud. Don't get me wrong, the response was still a good one, and very educational; just not the one i was expecting. sorry, i'll shut up now...


1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

As people said above, you must extern "C" the function somehow to make sure it gets a 'C; style calling convention. Also in a normal DLL build like with C/C++, you can put a .DEF file into the project with a list of functions to export. I don't know how to do either of these in C# myself.

Finally, it should be a 'global' function, not a method in a class, otherwise you'll have to jump thru some hoops to handle a 'this' pointer, so it's easier to just avoid that.

Share this post


Link to post
Share on other sites

I have tried out what you suggested all.

And it works.

I also make tried out other combinations so the conlusion:

__stdcall is not neccessary as it is the default, the compiler implicitly use it. (But obviously worthy to use it)

extern "C" is not neccessary. To export the function the definition file is enough.

Definition file is neccessary, if there is not definition file, the extern "C" or __declspec(dllexport) is useless.

thx for help, bb.

Now the example of the working DLL

#include "Mathy.h"
#include <stdexcept>

    int Addy(int a, int b)
    {
        return a + b;
    }

// Mathy.h

         int Addy(int a, int b);

EXPORTS
Addy

The Autoit source

Dim $result[50]
$dll = DllOpen("MathyDll.dll")
MsgBox ( 0, "Error Code, MathyDll.dll: ", @error )
$result = DllCall($dll, "int", "Addy", "int", 5, "int", 6 )
MsgBox ( 0, "Error Code", @error )
msgbox(0, "Res0", $result[0])  ; number of chars returned
msgbox(0, "Res1", $result[1])  ; Text returned in param 2
Exit

Share this post


Link to post
Share on other sites

awww. i was all giddy scrolling down to find valik's response to that line, absolutely sure that i was going to be laughing out loud. Don't get me wrong, the response was still a good one, and very educational; just not the one i was expecting. sorry, i'll shut up now...

Well, I started to respond to that comment but it wasn't going to be particularly amusing. Basically all I have to say on that subject is that it's pretty unreasonable to expect me to be able to (correctly) tell them the nuances of creating an AutoIt-compatible Dll in a language I don't know. As evidenced by the content of the post, when the OP switched to a language I did know, I provided sufficient information that should be useful in solving the problem(s). I was dissatisfied with the original wording and it wasn't funny, as you can see, so I scrapped that paragraph. I only mention it since you mention it.

Share this post


Link to post
Share on other sites

the extern "C" part may or may not be optional, a lot depends on the compiler your are using, command line arguments given to that compiler, and even the name of your source file. lots of compilers will treat a .c file differently than a .cpp file and infer the extern C based upon that. so sometimes you just get lucky and it works!

Share this post


Link to post
Share on other sites

Well, I started to respond to that comment but it wasn't going to be particularly amusing. Basically all I have to say on that subject is that it's pretty unreasonable to expect me to be able to (correctly) tell them the nuances of creating an AutoIt-compatible Dll in a language I don't know. As evidenced by the content of the post, when the OP switched to a language I did know, I provided sufficient information that should be useful in solving the problem(s). I was dissatisfied with the original wording and it wasn't funny, as you can see, so I scrapped that paragraph. I only mention it since you mention it.

Sorry, i didn't mean to imply that every one of your posts should be amusing; that line just kind of made it sound (to me) like the OP thought that you were expected to fix his code because he doesn't know how to do it himself, and from posts i've read of yours, that didn't seem like an assumption that would bode well with you. In the end i guess i was the only making inferences or assumptions, and have once again deteriorated the consistency of the thread. back to the corner for me...

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

__stdcall is not neccessary as it is the default, the compiler implicitly use it. (But obviously worthy to use it)

No, __stdcall is not implicit and it is necessary or you will corrupt the stack. The default calling convention is __cdecl. Not using __stdcall will cause the stack to become corrupted because objects are not destroyed (The stack is never cleaned up). While in practice, this doesn't seem to break anything, it's best to use __stdcall.

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