locked
Creating DLL's in unmanaged code with Visual C++ Express RRS feed

  • Question

  • Hi,

    I am a new user for Visual C++ Express and am trying to learn the basics of DLL creation, using unmanaged code.

    I create eLearning materials for educating others, and an eLearning authoring program (Opus Pro by Digital Workshop-UK) can use DLL's as long as they are written in unmanaged code. Opus uses a form of JavaScript (EMCA-262) to load a DLL and then call its functions. So, if I use unmanaged DLL's, I would need to know their function calls in order to specify these in correct JavaScript syntax so that they work when called in Opus.

    Using unmanaged DLL's would greatly extend the capabilities of an eLearning project, if I can learn how to create these DLL's.

    It would be very helpful to begin with a very basic DLL. I would appreciate any help getting started, leads, samples, , tutorials, step-by-step walk through to use VisualC++ Express to create an unmanaged DLL, etc.

    Thanks,

    Kind Regards,

    saratogacoach
    Wednesday, February 4, 2009 6:01 PM

Answers

  • The first place to check is the MSDN Library. Also, remember that Google is your friend. Type "create visual c++ DLL" and you will get lots of hits.

    Creating a DLL is trivial. Creating a DLL that can be called from Javascript is typically not trivial. The COM protocol in the past was typically recommended as a means of creating a DLL that can be called from any language that was COM-aware, which includes javascript. Perhaps Opus has provided some special Javascript functions for calling standard DLL's. You will need to check with them.
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:26 AM
    Wednesday, February 4, 2009 6:21 PM
  • As Brian said, read the documentation. There is a lot there that needs to be read. In particular, read Dynamic-Link Libraries. There is sample code there. One thing that is easily overlooked is the limitations of DllMain, but it is probably too soon to talka bout that. Also note that will need to use: extern "C", I hope you read the documentation about that.

    Also note that you can create a DLL project and have a small sample created for you.

    I am sure you can find many articles and tutorials that will help. Have you looked for a book?
    Sam Hobbs; see my SimpleSamples.Info
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:25 AM
    Thursday, February 5, 2009 4:04 AM
  • If there is an Opus forum then that would be the best place to ask about Opus.

    I think part of your education should be to write a test client; that is, write a program that calls your DLL. It can be a simple console program. You need to do this to understand how DLLs work and such. It will then be easier to understand what you need to do to call the DLL using Opus.

    Also, I have seen threads (discussions) get really big when people ask a question, then get answers, then ask another question, then get ......

    That can go on forever, so that is another reason to not try to solve the problems unique to Opus that are better answered by people familiar with Opus.
    Sam Hobbs; see my SimpleSamples.Info
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:26 AM
    Thursday, February 5, 2009 5:09 AM
  • The documentation in http://digitalworkshop.com/manuals/06Features.pdf is quite clear. Have you tried the sample that calls the Windows Message Box function? You can try that without writing any C++ code.

    If there is a way you can get a book about Windows programming, then you would have no problem understanding how to use CallFn.

    If you create a C++ Win32 project, and set the Application Type to DLL and check the Export Symbols checkbox in additional options, then you will get a sample DLL. I called my project "OpusDLL", so it has a function "fnOpusDLL" that returns a number. So calling it might be:

    var rv = MyDLL.CallFn("GetID", "slong");

    Don't forget to do the LoadDLL first.


    You should be able to just build that project after it is created and then use it for a quick test as above.



    Sam Hobbs; see my SimpleSamples.Info
    • Edited by Simple Samples Friday, February 6, 2009 5:06 AM
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:25 AM
    Thursday, February 5, 2009 6:05 PM
  •  I doubt you will find anything about CallFn in any Windows programming books.

    The first parameter for CallFn is the function name in the DLL; that I assume is clear. The next parameter is HasDisplay, and as I say, I am not sure if it is used. The third parameter is the "type" of the return value. The remaining parameters are pairs, where the first part is the "type" of a parameter forthe funtion in the DLL and the otehr part is the value.

    As you say, you need to be able to match the C++ "type" names to the corresponing Opus "type". An introductory C++ book will explain what you need to know to do that.


    Sam Hobbs; see my SimpleSamples.Info
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:23 AM
    Friday, February 6, 2009 5:19 AM
  • The sample I referred to is the one line:

    var rv = MyDLL.CallFn("GetID", "slong");

    I had had:

    var rv = MyDLL.MyDLL.CallFn("GetID", "slong");

    Notice that I had "MyDLL" twice.

    For C++ books, look at the book reviews in accu.org. There are probably good Windows programming books reviewed there and I don't have a recommendation myself. If you search this forum and other forums for "books" you will likely get help with that. Except I do recommend this, and for help using CallFn, see Fundamental Types.

    I will likely look at the CodeProject code later.

    C# is a lot like C++ so it is often relatively easy to convert code from C# to C++. There are some important differences so sometimes it won't be such a direct conversion.


    Sam Hobbs; see my SimpleSamples.Info
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:23 AM
    Friday, February 6, 2009 4:25 PM
  • That CodeProject project is for a Windows Forms User Control so unfortunately it won't be as easy to convert as you want it to be; you will need to learn about Windows programming and how to use Windows to draw in windows and related stuff.

    I have never seen the book Practical Object-Oriented Development in C++ and Java but based on the online information about it, it looks good. It might be too advanced for you now but you can consider it, if you can find a copy. Somewhere in the internet is a web site in which you can try the graphics application online but I have lost track of it.
    Sam Hobbs; see my SimpleSamples.Info
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:23 AM
    Friday, February 6, 2009 8:17 PM

All replies

  • The first place to check is the MSDN Library. Also, remember that Google is your friend. Type "create visual c++ DLL" and you will get lots of hits.

    Creating a DLL is trivial. Creating a DLL that can be called from Javascript is typically not trivial. The COM protocol in the past was typically recommended as a means of creating a DLL that can be called from any language that was COM-aware, which includes javascript. Perhaps Opus has provided some special Javascript functions for calling standard DLL's. You will need to check with them.
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:26 AM
    Wednesday, February 4, 2009 6:21 PM
  • Hi Brian,

    Thanks for your suggestions.

    Opus does use its script syntax to call a function in a loaded unmanaged DLL (from the Opus Pro 6 help guide):

    CallFn

    Syntax:

    CallFn( Function, HasDisplay, Return, params <Type, Value, Type, Value…> )

    Note that function names and representations of types (ulong, float etc) are surrounded by quotation marks while the actual values (numbers, true, false) are not. The chevrons bracketing the series of params are for clarity and need not be included.

    Return:

    A value of the type specified by the calling parameters. In the event of any error, the return value is -1.

    Parameters:

    Function – The name of the function to call. This must match the exported function name in the DLL. This parameter is required.

    HasDisplay – This allows you to specify whether the DLL call will display a user-interface and thereby allows the interface to be active. This is a boolean which means the two options are true or false. This parameter is required.

    Return – The type of the return value from the function (if any). This parameter is a string and must be one of the following values:

    Value

    C/C++ Data Type

    "none"

    void

    "uchar"

    unsigned char

    "schar"

    signed char

    "ushort"

    unsigned short

    "sshort"

    signed short

    "ulong"

    unsigned long

    "slong"

    signed long

    "float"

    float

    "string"

    unsigned char pointer (unsigned char*)

    Note: It is the responsibility of the DLL to ensure that the memory pointed to remains valid after the return of the function call.

    Note:

    Even if you do not intend to use the return value, if the DLL function declares one you must specify it in order for the function to be called correctly.

    Note:

    ecmascript (and therefore OpusScript) does not support unsigned values, so they will be converted to a signed value. This can result in conversion errors for very large unsigned values.

    Params – The parameters to be passed to the function. These parameters must be specified in pairs – the first is the type of the parameter and the second is the value to pass. integer numbers (unsigned long) or zero-terminated strings (char*)

    A special type is included, hwnd, which provides a handle to the Window the call is happening in (if appropriate). This allows DLL authors to make their displays as children of the Opus publication window and thereby (for example) centring their display in the the publication window. The value part of this type/value pair is ignored so we recommend that it is simply set to 0.

     

    Type

    Type declared in DLL function

    "ulong"

    unsigned long

    "slong"

    signed long

    "float"

    float

    "string"

    unsigned char*

    "hwnd"

    handle to window

    Remarks:

    This function allows functions within external DLLs to be called from OpusScript.

    Please be aware that ecmascript (and therefore OpusScript) is a loosely typed language; that is any variable can be treated as any type and will be automatically converted without warning.

              If a DLL requires more complex argument types than those supported by CallFn, it may be possible to write a "wrapper" DLL that contains a simplified interface that only uses data types          
              understood by OpusScript.

    Some examples from the Opus help guide:

    CallFn Examples

    Example 1:

    To load a DLL called MyDLL.dll and call a function called "Test") which takes no parameters and returns no value) in it:

    var MyDLL = LoadDLL( SYSTEM_PUBLICATION_DIR + "MyDLL.dll" );
    if (MyDLL)
    {
     // Call a function called Test with no return value (hence the "none" after the separating comma) and no parameters (simply not present)
     MyDLL.CallFn("Test", "none");
    }

    Example 2:

    Calling various example functions which take parameters and return values, using a DLL which is located in the publication directory and is therefore uses the SYSTEM_PUBLICATION_DIR as a path attached the name of the DLL:

    var MyDLL = LoadDLL( SYSTEM_PUBLICATION_DIR + "MyDLL.dll" );
    if (MyDLL)
    {
     // Call a function within the DLL
     var UserID = MyDLL.CallFn("GetID", "ulong", "string", USER_NAME);
     if (UserID != 0)
     {
      MyDLL.CallFn("SomeFunction", "none", "ulong", UserID );
     }
    }

    Example 3:

    It is also possible to call some Windows system functions, providing they take parameters that can be passed via OpusScript. For example, the MessageBox API function can be called as follows:

    var User = LoadDLL( SYSTEM_WINSYS_DIR + "User32.dll");
    if (User)
    {
     User.CallFn( "MessageBoxA", "slong", "hwnd", 0, "long", 0, "string", "This is a message box!", "string", "This is the title", "long", 48 );
    }

    The message box function is particularly useful for asking for feedback from users in a familiar way – for example asking if they really want to exit the publication.

              Further details on using the Window’s MessageBox with Opus can be found in the Using Windows Message Boxes topic. Full documentation for the Windows API can be found on Microsoft’s MSDN 
              website.

    Unfortunately, I'm a novice at the Visual C++ coding and don't know about what would be needed in an unmanaged DLL to be able to use it following the Opus syntax shown above.

    I'm not knowledgeable yet about COM. Not sure what this means, what would be needed.

    Any ideas, suggestions would be much appreciated. I very much would like to learn this, but need to start at "basics."

    For example, if I were able to start with a basic VC++ DLL (like a "Hello World" type basic project), perhaps get some source code that I can open in Visual C++ Express, study the code, identify the function calls (not sure how to do this), compile it and try loading the DLL and calling one of its functions in an Opus app, this would be a very helpful learning experience. Any leads would be welcomed.

    Kind Regards,

    saratogacoach

    Wednesday, February 4, 2009 7:33 PM
  • As Brian said, read the documentation. There is a lot there that needs to be read. In particular, read Dynamic-Link Libraries. There is sample code there. One thing that is easily overlooked is the limitations of DllMain, but it is probably too soon to talka bout that. Also note that will need to use: extern "C", I hope you read the documentation about that.

    Also note that you can create a DLL project and have a small sample created for you.

    I am sure you can find many articles and tutorials that will help. Have you looked for a book?
    Sam Hobbs; see my SimpleSamples.Info
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:25 AM
    Thursday, February 5, 2009 4:04 AM
  • Hi Sam,

    Thanks for your reply. I've been busy reading online, looking at examples, tutorials. And, while I don't understand it fully, yet, I did see a tutorial that mentioned need for the extern "C" showing that code, I think, in the .h file.

    The one significant area I can't figure out is how to call a sample function, using the Opus syntax for DLL function calls (see above). In Opus script, after loading the DLL, this looks something like:

    var UserID = MyDLL.CallFn("GetID", "ulong", "string", USER_NAME);

    based on the syntax: CallFn( Function, HasDisplay, Return, params <Type, Value, Type, Value…> )

    When I look at a sample file  (http://www.geocities.com/sujitmanolikar/dllhowto.html) (sample files: http://www.geocities.com/sujitmanolikar/cppdll.zip), I still can't figure out what to use for the Opus script function call. I need to learn more about what comprises a function call so I can translate it into the Opus script syntax.

    If anyone could take a look at the sample files (see http://www.geocities.com/sujitmanolikar/cppdll.zip) and suggest the items for the function call, this would be a great help, much appreciated. Then I can try to test in Opus to see how this all works (a big step forward).

    Again, thanks for your help.

    Kind Regards,

    saratogacoach
    Thursday, February 5, 2009 4:26 AM
  • If there is an Opus forum then that would be the best place to ask about Opus.

    I think part of your education should be to write a test client; that is, write a program that calls your DLL. It can be a simple console program. You need to do this to understand how DLLs work and such. It will then be easier to understand what you need to do to call the DLL using Opus.

    Also, I have seen threads (discussions) get really big when people ask a question, then get answers, then ask another question, then get ......

    That can go on forever, so that is another reason to not try to solve the problems unique to Opus that are better answered by people familiar with Opus.
    Sam Hobbs; see my SimpleSamples.Info
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:26 AM
    Thursday, February 5, 2009 5:09 AM
  • Hi Sam,

    Thanks for the suggestions.

    The DLL topic has been discussed regularly on the Opus forum but without further progress. The obstacle seems to be figuring out how to identify the DLL's function calls: CallFn( Function, HasDisplay, Return, params <Type, Value, Type, Value…> ) and correctly plug them into Opus script syntax. So far, it's been trial and error.

    So, I'll need to get a better understanding of unmanaged DLL function calls. For example, in the DLL in the above linked zip folder sample, it must have these function call items: just need to figure them out, try plugging them into Opus script in the correct syntax, see if they work.

    Several of the Opus forum posts discuss trying to get one or another DLL to work in Opus. I think some of these were managed code versions written in C#. Took a while to realize that managed code DLL will not work in Opus. Those in unmanaged code had their own challenges: figuring out items like "ulong," "short," etc. for the function calls. As mentioned, usually by "trial and error." 

    For a retired social worker like me, I suspect I should try to look for a forum for novices, amateur users just starting out.

    Again, much thanks for your kind help.

    Regards,

    saratogacoach

    Thursday, February 5, 2009 12:16 PM
  • The documentation in http://digitalworkshop.com/manuals/06Features.pdf is quite clear. Have you tried the sample that calls the Windows Message Box function? You can try that without writing any C++ code.

    If there is a way you can get a book about Windows programming, then you would have no problem understanding how to use CallFn.

    If you create a C++ Win32 project, and set the Application Type to DLL and check the Export Symbols checkbox in additional options, then you will get a sample DLL. I called my project "OpusDLL", so it has a function "fnOpusDLL" that returns a number. So calling it might be:

    var rv = MyDLL.CallFn("GetID", "slong");

    Don't forget to do the LoadDLL first.


    You should be able to just build that project after it is created and then use it for a quick test as above.



    Sam Hobbs; see my SimpleSamples.Info
    • Edited by Simple Samples Friday, February 6, 2009 5:06 AM
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:25 AM
    Thursday, February 5, 2009 6:05 PM
  • Thanks, Sam, for your suggestions regarding the Opus script for the function call.

    I will try to do some reading in Windows programming about CallFn. And some reading about writing a simple DLL in Visual C++ Express as a C++ Win32 project, like the one you describe that would fit the Opus CallFn.

    Over time, I've gotten some DLL's to work in Opus, but, as mentioned, not with any understanding, rather "trial and error" until it finally works.

    That's why I'm trying to learn more about this, so that rather than guessing, I can figure out the function calls and write them into correct Opus syntax. For example, it will be useful for me to learn why getting a return of a number in your example would use "slong" in the Opus script rather than another choice. That's some of what I need to understand.

    I took a look at your SimpleSamples.Info: looks like a rich depository of helpful information. I suspect I'll be back to look again.

    Thanks,

    saratogacoach
    Friday, February 6, 2009 4:19 AM
  • One important note: that sample code I provided might be incorrect; it is missing the HasDisplay parameter. I notice that all the samples of CallFn in that documentation are missing the HasDisplay parameter, so it is unclear whether it is to be used.

    Also, I just now noticed that I have "MyDLL" twice in my sample, which is incorrect, so I will fix that now.
    Sam Hobbs; see my SimpleSamples.Info
    Friday, February 6, 2009 5:06 AM
  •  I doubt you will find anything about CallFn in any Windows programming books.

    The first parameter for CallFn is the function name in the DLL; that I assume is clear. The next parameter is HasDisplay, and as I say, I am not sure if it is used. The third parameter is the "type" of the return value. The remaining parameters are pairs, where the first part is the "type" of a parameter forthe funtion in the DLL and the otehr part is the value.

    As you say, you need to be able to match the C++ "type" names to the corresponing Opus "type". An introductory C++ book will explain what you need to know to do that.


    Sam Hobbs; see my SimpleSamples.Info
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:23 AM
    Friday, February 6, 2009 5:19 AM
  • Hi Sam,

    Thank you for your very helpful replies.

    By the way, when you refer to a sample re: MyDLL used twice, is there a sample that you posted?

    As to "HasDisplay" I did some more research on the Opus side. Here's an Opus forum quote regarding display:

    false:- because you aren't using the display user interface

    The Opus help guide states:

    CallFn

    HasDisplay – This allows you to specify whether the DLL call will display a user-interface and thereby allows the interface to be active. This is a boolean which means the two options are true or false. This parameter is required.

    The example I found regarding displaying a user interface was display of a Windows message box.

    I still don't quite understand this (the reason I use a lot of "trial and error": first I would try "true" then see if the script works. If not, try "false").

    Also, as suggested, I will need to learn more from introductory material as to "type". Which introductory programming book for C++ would you recommend?

    I came across a DLL on code project a few days ago that has many features that I eventually need to create for an Opus project: it allows the user in runtime to do some drawing. However, the DLL is written in C#. I wonder, if I can learn more about writing C++ DLL's, if I will be able to "translate" the drawing functions into C++. If you could take a look at the C# DLL, I would appreciate any ideas about whether the conversion is do-able, what may be involved. This may be quite a challenge, but my ability to add a drawing DLL to an educational project in Opus will be significant (plus I would have to figure out how to add a way for the user to save their drawing so they can return to it and edit or add to it).

    C# Drawing DLL: http://www.codeproject.com/KB/dialog/Basic_Drawing_Plug_in.aspx

    With you assistance, I am learning a lot! :)

    Again, thanks very much for your help.

    Kind Regards,

    saratogacoach




    Friday, February 6, 2009 2:00 PM
  • The sample I referred to is the one line:

    var rv = MyDLL.CallFn("GetID", "slong");

    I had had:

    var rv = MyDLL.MyDLL.CallFn("GetID", "slong");

    Notice that I had "MyDLL" twice.

    For C++ books, look at the book reviews in accu.org. There are probably good Windows programming books reviewed there and I don't have a recommendation myself. If you search this forum and other forums for "books" you will likely get help with that. Except I do recommend this, and for help using CallFn, see Fundamental Types.

    I will likely look at the CodeProject code later.

    C# is a lot like C++ so it is often relatively easy to convert code from C# to C++. There are some important differences so sometimes it won't be such a direct conversion.


    Sam Hobbs; see my SimpleSamples.Info
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:23 AM
    Friday, February 6, 2009 4:25 PM
  • Thanks, Sam.

    I am plowing ahead, reading, experimenting.

    I look forward to your thoughts about how to convert the C# drawing DLL at the CodeProject to an unmanaged C++ DLL that I could use within an Opus project. I've looked and looked at the files, source code, but as yet can't figure them out, so I'm a long way from making a successful conversion, plus identifying the converted function calls in a way that permits me to put them into Opus DLL CallFn syntax.

    Again, thanks much for your kind help!

    Regards,

    saratogacoach
    Friday, February 6, 2009 5:40 PM
  • That CodeProject project is for a Windows Forms User Control so unfortunately it won't be as easy to convert as you want it to be; you will need to learn about Windows programming and how to use Windows to draw in windows and related stuff.

    I have never seen the book Practical Object-Oriented Development in C++ and Java but based on the online information about it, it looks good. It might be too advanced for you now but you can consider it, if you can find a copy. Somewhere in the internet is a web site in which you can try the graphics application online but I have lost track of it.
    Sam Hobbs; see my SimpleSamples.Info
    • Marked as answer by Wesley Yao Wednesday, February 11, 2009 2:23 AM
    Friday, February 6, 2009 8:17 PM
  • Thanks again, Sam.

    It's too bad that the Drawing DLL will be extra challenging for someone just learning. But, it can serve as a goal.

    Kind Regards,

    saratogacoach
    Friday, February 6, 2009 9:11 PM