Introduction
There are 5 ways to incorporate complex functions in GoldSim models:
- Native functions written in GoldSim script elements
- Native functions defined in GoldSim elements within looping containers
- Functions written in MS Excel that link to GoldSim using Spreadsheet elements
- External functions (DLLs) that link to GoldSim using External elements
This article will illustrate the last option: Link to GoldSim using External elements. Specifically, this article describes how to employ an external program written in C/C++ from within GoldSim.
DLLs and the GoldSim External Element
GoldSim allows users to develop separate program modules (written in C, C++, Fortran or any other compatible programming language) which can then be directly coupled with GoldSim models. This article explains how to create such an external function module using a compiled C program and create the interface with GoldSim. Example source code, a DLL, and a GoldSim model file are provided to help illustrate the concepts presented in this article. See below for links to download the example materials.
External functions interface with GoldSim’s External elements to do calculations or other manipulations that are not included in the standard capabilities of GoldSim. The external function facility allows special purpose calculations or manipulations to be accomplished with more flexibility, speed or complexity than with the standard GoldSim element types. The external functions are bound to the GoldSim executable code at run time using DLL technology. The DLL files should be present in the same folder as the GoldSim .gsm file, in the same folder as the GoldSim executable file, or elsewhere in the user’s path.
The acronym “DLL” stands for Dynamic Link Library, which is Microsoft’s implementation of the shared library concept in the Microsoft Windows and OS/2 operating systems. By using a DLL, a program can be modularized into separate components. A DLL is like an executable program (exe) that is compiled from source code. For example, a thermodynamics program (written in C) may run in parallel with a GoldSim water management model. DLLs execute in the memory space of the calling process (e.g. GoldSim). Because the modules are separate, the load time of the program is fast, and a module is only loaded when that functionality is requested.
It is easier to build functionality and even subroutines natively within the GoldSim modeling framework. Compartmentalizing functions into external DLLs has benefits but makes the overall model less transparent and more difficult to maintain for users that are not proficient in programming at a lower level. Usually, an external function is employed when existing legacy programs must be interfaced with GoldSim and there is not time to build that functionality in GoldSim. External functions should provide their own error handling, message handling, file management and memory management if required. It is essential that when it receives a “clean up” request, an external function should release any acquired memory and close any open files.
Before continuing, it is highly recommended that you read the section of the User Manual that describes GoldSim’s External element. If you are in GoldSim, click on the help button and browse in the Contents to the location shown below.
Writing C Programs and Compiling DLLs
You can write a C or C++ program with little more than a basic text editor like Notepad and some programming experience. There are many websites with introductions to C programming, like this one: http://cplus.about.com/od/learningc/Learn_How_to_Write_Programs_in_C.htm. If you are not familiar with C/C++, it is highly recommended that you take the time to practice to gain a basic understanding before diving into External elements in GoldSim. If you skip this step and march into connecting an existing C program to GoldSim, you will likely run into problems and become frustrated.
Once the C/C++ program is written, you need to compile the code into an executable program . In our case, the type of program we are compiling to is a DLL. The best option for compiling C programs into a DLL is with Microsoft Visual Studio. This is going to be the most straight-forward option for Windows users because it doesn’t involve much set up and the tool is made to create Windows programs with the use of Wizards that create template structure for you. Instructions for writing C/C++ code and compiling to DLL can be found on the msdn website (see msdn.microsoft.com/en-us/library/ms235636(v=vs.80).aspx).
Microsoft provides different editions of Visual Studio:
- Visual Studio Standard/Professional
- Visual Studio Express
The Express version is free but lacks a lot of functionality and features that might be useful for large projects. For learning and testing purposes, you should have everything you need in the free edition (Visual Studio Express).
Alternatively, a GNU compiler called GCC is available, which can be downloaded for free from here: http://gcc.gnu.org/. For Windows users, this compiler requires installation of the MinGW development environment. This option may require more configuration and setup before you will be ready to compile DLLs.
Implementing an External Function
The C program must be configured in a way that allows GoldSim to communicate with the DLL. The most basic setup is to have a single file that contains both the DLL interface and the functions. This type configuration is illustrated below.
This setup is fine for testing purposes but for any real-world projects, you will want to organize your external functionality into at least the following 4 components:
- GoldSim Model with an External element
- DLL interface
- Library header file
- Function Definitions
This configuration is illustrated below. Note that the Function Definitions may include multiple files but we only use a single file for this example.
Details on how to set up the DLL Interface are described in Appendix C of the GoldSim User Manual. This Appendix will walk you through the definitions and requirements for the following concepts:
- Restrictions
- External Function Format
- Argument Checking
- Input and Output Argument Arrays
- External Function Examples
- DLL Calling Sequence
- DLL Calling Details
Before continuing, it is highly recommended that you first read through Appendix C of the manual at this time.
External Function Application
This section introduces working examples that employ the two approaches illustrated above (single C file and multiple C files) for performing very simple functions outside of GoldSim. The first example uses a single C file to interface with GoldSim and define the external functions. It is recommended that you start with this example before moving to the next one. The second example uses 3 C files for the interface, library headers, and the actual functions being carried out. This second example would likely be the type of setup you would use in a real-world project.
Single C File Example
The single C file (download using the link below) contains code for the GoldSim interface. The linkage between GoldSim and the C/C++ code is established using the expression shown below:
This expression must be used for all C and C++ DLLs. The components of this expression are described in Appendix C of the User Manual. C and C++ external functions use the “void” function because the function cannot return output. Some brief facts about the function are listed below:
- The function name and argument names can be different from those shown above
- __declspec(dllexport) makes the function visible outside the DLL
- methodID specifies the action that the external function must perform
- status is a number indicating the status of the external function
- inargs is an array of input arguments
- outargs is an array that returns outputs from the external function
The section of code labelled as “Actions to Perform” is intentially left out for clarity. This section detailed in the snippet below:
GoldSim tells the external function which action to perform using a list of variables. These are shown below.
These Arguments are fully described in Appendix C of the User Manual. The next part of the program tells GoldSim the status of the program and instructs GoldSim on how to proceed.
The part of the code that is doing the external functions is the part shown below:
The variable name “outargs” refers to the results of the external function that get returned to GoldSim. The variable name “inargs” is the name for parameters that come from GoldSim and are used inside the external function.
On the GoldSim side, we create an External element and reference 2 numbers in the input side of the interface. The output of the External Function (DLL) will then return the Sum and Product results to the Externa element as output, which can be referenced in GoldSim. The following screen capture illustrates how this would be set up.
The External element interface is set up as shown in the following screen capture:
The names of the arguments “num1” and “num2” do not need to match any names in the external function. The input on the first row of the Input Interface Definition will refer to “inargs[0]” in the external function. In this example, the input variables are interfaced to the DLL as follows:
Table 0.1 - GoldSim to DLL Interface
GoldSim Element ID |
DLL Input Name |
External Function Argument Name |
y |
num1 |
inargs[0] |
x |
num2 |
inargs[1] |
The output results are interfaced with GoldSim as follows:
Table 0.2 - DLL to GoldSim Interface
External Function Argument Name |
GoldSim Output Name |
GoldSim Element ID |
outargs[0] |
DLL.Sum |
Sum |
outargs[1] |
DLL.Product |
Product |
While it is nice that the entire example is contained in a single file, it is not very practical because the code would become very messy if we tried to fit it all on a single page. What we really want to do is separate the different components of the program in different files, as is demonstrated in the following example.
Multiple C File Example
This example uses a DLL that was compiled from 3 different source files:
- GoldSim Interface File
- Library Header File
- External Function File
Each of these can be downloaded using the link below. The main difference between the multiple C File Example and the Single C File example is that rather than explicitely define functions in the “void __declspec” routine. Instead, we just refer to the function names and use a different file to define the actual functions. This method is much cleaner. The XF_CALCULATE function is now as follows:
These functions are included in this file using the #include statement at the top of the page:
The Function_Library.h file contains the declarations for each of the functions:
Finally, we see the contents of the Function Library itself, which contains the definitions of the external functions
On the GoldSim side, we create an External element and reference 2 numbers in the input side of the interface. The output of the External Function (DLL) will then return the Sum and Product results to the Externa element as output, which can be referenced in GoldSim. The following screen capture illustrates how this would be set up.
The External element interface is set up as shown in the following screen capture:
The names of the arguments “num1” and “num2” do not need to match any names in the external function. The input on the first row of the Input Interface Definition will refer to “inargs[0]” in the external function. In this example, the input variables are interfaced to the DLL as follows:
Table 0.3 - GoldSim to DLL Interface
GoldSim Element ID |
DLL Input Name |
External Function Argument Name |
y |
num1 |
inargs[0] |
x |
num2 |
inargs[1] |
The output results are interfaced with GoldSim as follows:
Table 0.4 - DLL to GoldSim Interface
External Function Argument Name |
GoldSim Output Name |
GoldSim Element ID |
outargs[0] |
DLL.Sum |
Sum |
outargs[1] |
DLL.Product |
Product |
outargs[2] |
DLL.Quotient |
Quotient |
outargs[3] |
DLL.Difference |
Difference |
Comments
0 comments
Please sign in to leave a comment.