Thread: dll file

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    4

    dll file

    I need to make dll file for computing user defined function in Lindo Lingo. I need to implement two new functions, but I can make only one myuser.dll file for use in Lingo.
    But, talking with people from Lindo, it is possible to make two argument myuser.dll function, with first first argument as a "branching" variable. for example, For example,
    @USER( 1, 2.4)
    might compute the sin of 2.4, while
    @USER( 2, 2.4)
    would compute the cosine of 2.4. The first argument of 1 implies return the sin, while a first argument of 2 implies return the cosine.

    My question is how to do that, because I am new to Vc++.
    Thanks in advance,
    Aleksandar

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So what do you have a question about? Do you know how to write a function? Do you know how to make a .dll file? Is there an actual reason why you have to only have one name (a .dll can have many many many many many many functions inside it)?

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    4
    I know how to make .dll file, and my question is how to write a function. There is actual reason to have only one name, because of Lingo language. When Lingo starts up, it searches for .dll file named MYUSER.dll. If he finds him, it loads .dll into memory and calls the exported MYUSER routine every time when it needed.

  4. #4
    Registered User
    Join Date
    May 2011
    Posts
    4
    This is an example from lingo manual, but only for one function. I need it for two.

    User Defined Functions
    The @USER function allows the use of custom functions of your own design in LINGO. In Windows
    versions of LINGO, you provide a Dynamic Link Library (DLL) that contains your @USER function.
    Most programming languages that support Windows should allow you to build a DLL. For platforms
    other than Windows, you provide LINGO with a compiled C or FORTRAN subroutine containing
    your @USER function.
    From the perspective of a LINGO modeler, an @USER function is a function that can take any number
    of arguments, but must take at least one. It returns a result calculated by the user-written routine.
    From the perspective of the programmer writing the custom function, an @USER function takes only
    two input arguments and returns a single result. The two input arguments consist of:
    1. an integer specifying the number of arguments encountered in the @USER
    reference in the LINGO model, and
    2. a vector containing the values of the arguments in the order in which they
    were encountered in the @USER reference in double precision format (i.e.,
    an 8 byte floating point format).
    In other words, although to the LINGO modeler an @USER function can appear to take any number of
    arguments, to the programmer implementing the @USER function, only two input arguments are
    passed.
    It is possible to use multiple functions with @USER by writing and compiling each function as a
    separate subroutine and taking an argument to @USER as the index number of the subroutine that you
    want to branch to.
    Installing @USER Under Windows
    When LINGO for Windows starts up, it searches for the DLL file called MYUSER.DLL. LINGO
    searches for this file in your startup directory. The startup directory is the directory where you
    installed the LINGO program. If LINGO finds MYUSER.DLL, it loads the DLL into memory and calls
    the exported MYUSER routine every time a model references an @USER function.
    On platforms other than Windows, you must link a compiled FORTRAN or C subroutine with the
    LINGO libraries in order to provide a customized @USER function. Refer to the README file for
    your version of LINGO for technical information on how to link your custom routines with LINGO.
    In the following section, we illustrate the details of building such a DLL using Microsoft Visual C++.
    Visual C++ Example
    In this section, we will use Microsoft Visual C/C++ to create a 32-bit DLL that contains an @USER
    function to perform the square root function. This is very easy to do if we make use of the AppWizard
    in Visual C++ to build the base code for the DLL. Or, you will find the code for this example in the
    USER\VC++ subdirectory off of your main LINGO directory. To build the base code, start the Visual
    C++ Developer Studio and do the following:
    1. Issue the File|New command.
    2. You should now see a New dialog box. Select the Project Workspace
    options and then click OK.
    3. You will now see a New Project Workspace dialog box. Give the project the
    name sqroot. In the Type box, select the MFC AppWizard (dll) option. Click
    on the Create button.
    4. A new MFC AppWizard dialog box should appear. Simply click on the
    Finish button.
    5. You should now see a New Project Information box containing a summary
    of the options selected for your project that resembles:
    Click the OK button to finish creating the base code for our DLL.
    Now, edit the SQROOT.CPP file and add the modifications listed below in bold:
    [sqroot.cpp : Defines the initialization
    Code:
    // routines for the DLL.
    //#include "stdafx.h"
    #include "sqroot.h"
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    /////////////////////////////////////////////////////
    // CSqrootApp
    BEGIN_MESSAGE_MAP(CSqrootApp, CWinApp)
    //{{AFX_MSG_MAP(CSqrootApp)
    //NOTE-the ClassWizard will add and
    // remove mapping macros here.
    // DO NOT EDIT what you see in these
    // blocks of generated code!
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    CSqrootApp::CSqrootApp()
    {
    // The constructor
    // Remove next line for a "quiet" version
    // of MyUser.DLL
    AfxMessageBox("@USER DLL installed");
    }
    CSqrootApp theApp;
    #include <math.h>
    extern "C" __declspec(dllexport)
    void MyUser(int* pnNumberOfArgs,
    double* pdArgs, double* dResult)
    {
    // This is an @USER routine callable by LINGO. In
    // this particular case we simply take the
    // square root of the first argument.
    *dResult = sqrt(*pdArgs);
    }
    Code:
    [/QUOTE]
    [/CODE]You should now be able to build the DLL. When Visual C++ completes the build, copy the
    SQROOT.DLL file to LINGO’s startup directory (the one where LINGO13.EXE or LINGO64-13.EXE
    is located) and rename SQROOT.DLL to be MYUSER.DLL. Now, start LINGO and you should see the
    following dialog box confirming the DLL was successfully loaded:
    Input a small model to compute the square root of 9 and solve it to get the following results:
    If

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So your other tool only looks for one function, despite however many there are. That's fine. I have no idea how you could have gotten to "can make a DLL" without going through "writing a function", so ... well done for that, I guess. Did you read the example you posted? There's an example of what the function must look like, in terms of prototypes; and they even tell you what each argument is: the first is the number of arguments provided by the user, the second is an array (possibly) of the arguments that were provided, and the third is where you need to put the answer.

  6. #6
    Registered User
    Join Date
    May 2011
    Posts
    4
    Thanks for quick answer. But I still don't know how to do that, because I am new in VC++.
    They said that it is possible to use multiple functions with @USER by writing and compiling each function as a
    separate subroutine and taking an argument to @USER as the index number of the subroutine that you
    want to branch to.
    I am interested how to do that.
    Thanks in advance.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    A web forum is not somewhere where you can learn C++ from scratch.

    "They said that it is possible to use multiple functions with @USER by writing and compiling each function as a
    separate subroutine and taking an argument to @USER as the index number of the subroutine that you
    want to branch to."
    This is trivial -- you just call the function you want to call, based on the first parameter. If the first parameter is 1, you call function_A. If the first parameter is 2, you call function_B. This is more-or-less the second thing you do when you are learning functions. So: go forth and learn C++.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 03-08-2010, 02:43 PM
  2. Replies: 2
    Last Post: 03-04-2010, 04:19 AM
  3. Replies: 3
    Last Post: 11-21-2006, 07:26 PM
  4. Replies: 4
    Last Post: 07-06-2006, 02:53 AM
  5. Replies: 12
    Last Post: 03-10-2005, 07:48 PM