5 Replies - 1640 Views - Last Post: 22 November 2011 - 03:10 PM Rate Topic: -----

#1 Leo's Sire  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 36
  • Joined: 19-November 11

Using c++ dll in c#

Posted 19 November 2011 - 03:25 PM

I have written product selection programs for my work in vb6 (as our suppliers dll uses variants and our supplier gives example code for vb6) but I would like to progress my coding capability so i want to rework it into c#. I have read books and tutorials but the one thing holding me back is a little discussed topic from what I can research.

I want to declare my suppliers function (which returns nothing, it alters the array given in the declaration / call i.e. "byRef" in vb6)

It needs the basic info shown below and when run will alter the output array and allow me to use it as my needs see fit. You will notice my 'console.writeline' example which calls on the output array, item 30.

My suppliers dll is a COM dll, which cant be loaded as a reference. if it could, life would be infinitely easier.

The dll is supposed to be fed with an array of double type, and then the output and options are supposed to be variant type which I tried using object. I know I can make a type variant which I will do but I don't think I am that far yet.

Anyone with a history from vb6 will probably understand my train of thought from what I have tried.

Any help to a fledgling c# programmer would be greatly received.

Thank you in advance.

Joe


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections;
using System.Runtime.InteropServices;

namespace Supplier_Dll
{

    public class SupplierDll
    {

        [DllImport("Supplier.Dll")]
        public static extern void Startjob(double[] input, object[] results, object[] options)
        {
            //return results; removed as the method alters the 'results' array accordingly. 
        }

    }
    class Program
    {

        static void Main(string[] args)
        {
            double[] InfoInput;
            object[] InfoOutput ;
            object[] InfoOptions ;

            InfoInput[0] = 0;
            InfoInput[1] = 32 ;
            InfoInput[2] = 50 ;
            InfoInput[5] = 2000 ;
            InfoInput[14] = 4; 
            InfoInput[15] = 10 ;
            InfoInput[16] = 2; 
            InfoInput[17] = 4; 
            InfoInput[18] = 500 ;
            InfoInput[26] = 7; 
            InfoInput[27] = 12 ;
           
     SupplierDll.Startjob(aInput[0],  aOutput[0],  aOptions[0]);

Console.WriteLine("Output: {0}", aOutput[29]);
        
       }
   }
}




Is This A Good Question/Topic? 0
  • +

Replies To: Using c++ dll in c#

#2 born2c0de  Icon User is offline

  • printf("I'm a %XR",195936478);
  • member icon

Reputation: 180
  • View blog
  • Posts: 4,667
  • Joined: 26-November 04

Re: Using c++ dll in c#

Posted 21 November 2011 - 02:30 PM

There's a couple of things that you can change.
  • External Function Calls do not have a function body. Just provide its prototype like this:
    [DllImport("Supplier.Dll")]
    public static extern void Startjob(double[] input, object[] results, object[] options);
    
    

  • Your function expects an array but you're passing the first element instead of the entire array. Your function call should look like this:
    SupplierDll.Startjob(aInput,  aOutput,  aOptions);
    
    

  • (I'm not 100% certain about this) Whenever an array is returned by a function, you need to specify the out keyword for the parameters like this:
    [DllImport("Supplier.Dll")]
    public static extern void Startjob(double[] input, out object[] results, object[] options);
    //...
    //...
    //...
    SupplierDll.Startjob(aInput,  out aOutput,  aOptions);
    
    

    I've assumed that only the aOutput array is returned by the DLL. You will need to add the out keyword to the options array as well.


Your code should be able to compile now. Let me know how it goes.
Was This Post Helpful? 0
  • +
  • -

#3 Leo's Sire  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 36
  • Joined: 19-November 11

Re: Using c++ dll in c#

Posted 21 November 2011 - 03:31 PM

Hello, born2code

Thank you that was very helpful. The code would now work if my supplier had created the dll with a suitable entry point. But it fails to find one and stalls.

The C/C++ code for loading the function is
extern "C" BOOL FAR PASCAL EXPORT StartJob(double vInp[100], VARIANT vRis[100], double
vOpt[1]);



while the vb6 code for loading the function is

Declare Function StartJob Lib "calcdll.dll" (ByRef p1 As Double, ByRef p2 As Variant, ByRef p3 as Double) As Boolean



I have used the vb6 code extensively. with a simple
a = StartJob(ainput(0),aresult(0), aoptions(0))



This allows me to use aresuls(#) as i wish,
for instance
msgbox("Output: " & aresult(29))



Setting up the dll in this manner seems to not look for an entry point. Is this something which can be done in c#?

I have tried returning the function in c# by changing the 'void' for 'boolean' and creating a boolean variable call "a" then
a =  SupplierDLL.StartJob(aInput, aOutput,  aOptions);


but to no avail.

Thank you in advance, again.
Was This Post Helpful? 0
  • +
  • -

#4 born2c0de  Icon User is offline

  • printf("I'm a %XR",195936478);
  • member icon

Reputation: 180
  • View blog
  • Posts: 4,667
  • Joined: 26-November 04

Re: Using c++ dll in c#

Posted 21 November 2011 - 04:19 PM

Could you attach the DLL file (or email it to me) here?
There's a good chance that the function name has been mangled which is why the code can't find the entry point. If that's the case, I can reverse engineer the DLL file and find the entry point.
There's also a chance that the DLL function is StartJob() and not Startjob() (function names are case sensitive).
Make 'j' as an uppercase character and see if that works.
Here's a cleaner alternative to specify an entry point.
[DllImport("Supplier.dll", EntryPoint="StartJob")]
public static extern void Startjob(ref double[] input, out object[] results, out object[] options);
//...
//...
//...
SupplierDll.Startjob(ref aInput,  out aOutput, out aOptions);


This post has been edited by born2c0de: 21 November 2011 - 04:29 PM

Was This Post Helpful? 0
  • +
  • -

#5 Leo's Sire  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 36
  • Joined: 19-November 11

Re: Using c++ dll in c#

Posted 22 November 2011 - 02:20 AM

Hello, it was in fact the capital J in the StartJob function.

But the results array is now just returning null values throughout, it doesn't seem to be altering the results array.

The 'out' ref isn't needed.

It could be it's expeceting a variant type array and im passing an object array.

I will try creating a varient type and then using that for my result array definition.
Was This Post Helpful? 0
  • +
  • -

#6 Leo's Sire  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 36
  • Joined: 19-November 11

Re: Using c++ dll in c#

Posted 22 November 2011 - 03:10 PM

Still stuck, i am starting to think this is not possible. i have managed to create the following which seems to pass the data to the function but it doesn't change the results array. I think this may be a result of not being able to use a variant.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections;
//using System.Runtime.InteropServices; // DllImport

namespace SupplierDLL
{
 
    public class SupplierDll
    {

        [DllImport("TheDLL.Dll")]
        public static extern void StartJob(double[] input, object[] results, object[] options);
        
    }
    class Program
    {

        static void Main(string[] args)
        {
            double[] aInput = new double[100];
            object[] aOutput = new string[100];
            object[] aOptions = new object[1];
            
            aInput[0] = 0;  
            aInput[1] = 32 ;            
            aInput[2] = 50 ;
            aInput[5] = 2000 ;
            aInput[14] = 4; 
            aInput[15] = 10 ;
            aInput[16] = 2; 
            aInput[17] = 4; 
            aInput[18] = 500 ;
            aInput[26] = 7; 
            aInput[27] = 12 ;
           
      SupplierDLL.StartJob(aInput, aOutput,  aOptions);

     Console.WriteLine("Output: {0}", aOutput[29]);
      
        
   }
    }
}




I have expanded the array going in and this looks correct, but when I expand the aOutput it remains Null.

Getting close to giving up.

Thank you to anyone who can help.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1