Jump to content

Recommended Posts

Posted (edited)

I know this is a developers forum, but i think this belongs here.

I've tried making a simple math dll in visual studio 2010 following the walkthrough here

It built successfully, but the call from autoit returns @error = 3 "function" not found in the DLL file

mathdll.h

namespace MathFuncs
{
    class MyMathFuncs
    {
    public:
        // Returns a + b
        static __declspec(dllexport) double Add(double a, double <img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' />;

        // Returns a - b
        static __declspec(dllexport) double Subtract(double a, double <img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' />;

        // Returns a * b
        static __declspec(dllexport) double Multiply(double a, double <img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' />;

        // Returns a / b
        // Throws DivideByZeroException if b is 0
        static __declspec(dllexport) double Divide(double a, double <img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' />;
    };
}

mathdll.cpp

#include "MathDll.h"

#include <stdexcept>

using namespace std;

namespace MathFuncs
{
    double MyMathFuncs::Add(double a, double <img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' />
    {
        return a + b;
    }

    double MyMathFuncs::Subtract(double a, double <img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' />
    {
        return a - b;
    }

    double MyMathFuncs::Multiply(double a, double <img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' />
    {
        return a * b;
    }

    double MyMathFuncs::Divide(double a, double <img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' />
    {
        if (b == 0)
        {
            throw new invalid_argument("b cannot be zero!");
        }

        return a / b;
    }
}

#include <Array.au3>
$dll = DllOpen("mathdll.dll")
ConsoleWrite(@error & @LF)
If $dll = -1 Then
    MsgBox(0, "", "")
    Exit
EndIf
$call = DllCall($dll, "double", "Multiply", "double", 2, "double", 4); tried Add, Subtract, Divide. And "double:cdecl" as return type.
ConsoleWrite(@error & @LF)
DllClose($dll)
ConsoleWrite(@error & @LF)
_ArrayDisplay($call)

My question is, are there any settings I need to employ in the C++ project properties that are needed for a dll to work with autoit, or am I making a schoolboy error?

The console output is...

0

3

0

Appreciate anyones time. Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Posted

Does this help?

http://www.autoitscript.com/forum/index.php?showtopic=113441

I don't know about vc++, but I know that c# dlls are a different format to normal ones, and so can't be used from AutoIt. I'd try it with plain c++ (e.g. make a win32 program in the wizard)

Posted

I dont know what file level functions are, but I mostly followed this tut in the end.

File level is not in a namespace or class. For example, all AutoIt functions are at file level, whereas c#'s methods are all in classes which are in namespaces.
Posted

I see, then I think what I have are file level.

It is this format

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

With some prototypes and then the functions themselves.

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Posted (edited)

I have a little question, about DllMain if anyone can answer it for me.

Regarding the code above, in DllMain the switch "switch (ul_reason_for_call)".

Does an Autoit3 DllOpen/DllCall involve any of the given cases ?

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Posted

Yes, I presume AutoIt uses the LoadLibrary function so that when you open a dll, it calls with DLL_PROCESS_ATTACH, and with DllClose it will use DLL_PROCESS_DETACH

You can test that easily enough.

Posted (edited)

According to (http://en.wikibooks.org/wiki/Windows_Programming/Dynamic_Link_Libraries)

DLL_PROCESS_ATTACH -- a new program has just linked to the library for the first time.

DLL_PROCESS_DETACH -- a program has unlinked the library.

DLL_THREAD_ATTACH -- a thread from a program has linked to the library.

DLL_THREAD_DETACH -- a thread from a program has just unlinked the library.

" ...if you aren't interested in any of the reasons, you can remove the entire switch statement from your program and return TRUE."

Edited by jaberwocky6669
Posted

Thanks gentlemen.

That being true, what I am intersted in is a way to employ "LPVOID lpReserved" from a DllOpen in Autoit, like passing it an argument??

I have a feeling I'm not going to get the answer I want, but I looked much sillier before this so I wont be braeking my record.

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Posted

You cannot pass an extra parameter to DLLMain.

Waht is the param you want to pass?

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Posted (edited)

I'm after a function in the dll to be executed, but only once upon it being opened, and using a parameter passed.

The paramater type is not important to me, It can be any type available in Autoit.

EDIT: except bool.

For instance concider this psuedo

I use DllCall($dll, "int", "func")

$Dll is opened, and another internal function is performed, then "func" and the dll is closed.

I use DllOpen($dll,"int",12345)

DllCall($dll, "int", "func2")

DllCall($dll, "int", "func3")

DllClose($dll)

$Dll is opened, and another internal function is performed, then "func"

then "func2" them "func3"

and the dll is closed.

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Posted (edited)

Wouldn't this work?

BOOL APIENTRY DllMain(MODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        // function();
        break;

        case DLL_THREAD_ATTACH:
        break;

        case DLL_THREAD_DETACH:
        break;

        case DLL_PROCESS_DETACH:
        break;
    }
    
    return TRUE;
}
Edited by jaberwocky6669

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
×
×
  • Create New...