How to pass structure variable to DLL

Discussion in 'Questions (Windows Mobile)' started by DaveW, Dec 4, 2008.

  1. DaveW

    DaveW Active Member Licensed User

    I am trying to port the more processor intensive portions of my program to DLLs to speed the operations up. I have succeeded with some image based processes and would like to do some based on structure variables. However I have no idea how I can pass a structure variable that is defined in B4PPC to a C# function in a DLL. I am sure it must be possible - but how?!

    If for example I have:

    Code:
    Sub Globals
                
    Dim Type(Name, ID, Age) person
    End Sub
    how can I create a B4PPC procedure:
    Code:
    MyProc(person)
    that links to:
    Code:
    public void MyProc(some_struct_name aperson)
    David.
     
  2. agraham

    agraham Expert Licensed User

    Like this, as an array

    Code:
    Sub Globals
      
    Dim Type(Name, ID, Age) person ' default type is String
      Dim Type(Name, ID, Age persons(2' 2D array
      Dim Type (X, Y) points(10,10As Int32 ' typed 3D array
      Dim array3D (10,10,10As Double ' another typed 3D array
    End Sub

    ' B4PPC procedures:
    Lib.MyProc(person())

    Lib.AnotherProc(persons())

    Lib.YetAnotherProc(points())

    Lib.LastProc(array3D())


    ' library methods:
    public void MyProc(String[] aperson)

    public void AnotherProc(String[,] somepersons)

    public void YetAnotherProc(Int32[,,] somepoints)

    public void Last(Double[,,] a3Darray)
     
  3. DaveW

    DaveW Active Member Licensed User

    Ahhhh!!!!

    Thank you, as always Andrew:)
     
  4. DaveW

    DaveW Active Member Licensed User

    Thinking about it some more.... Once I get the structure variable in the method, do I have to treat it as an array of strings? So in B4PPC I can reference Person.Age but in the DLL method would it have to be Person[2] ?
     
  5. agraham

    agraham Expert Licensed User

    Yes Person.Age or Person(2) in Basic4ppc and Person[2] in C#. There is no way of passing the "structure" names across.
     
  6. DaveW

    DaveW Active Member Licensed User

    :sign0148: That's going to be fun - I have 24 fields in my structure to keep straight :(
     
  7. Erel

    Erel Administrator Staff Member Licensed User

    Structure names are removed by the parser during compilation.
    The parser converts structures to regular arrays.
     
  8. agraham

    agraham Expert Licensed User

    While you can't pass arbitrary names to a library you can, if your library knows what it is expecting, predefine an enumeration to use as array indices. Look up "enum" in your C# docs.
     
  9. DaveW

    DaveW Active Member Licensed User

    I think my C# docs will have to be a Christmas present ;)
    Any recommendations for a good C# book?
     
  10. agraham

    agraham Expert Licensed User

    My bible is "The Complete Reference to C# 2.0 by Herb Schildt", Osborne, ISBN 0-07-2266209-5. I don't know where you are based but anyone in the UK should check out The Book Depository if they don't already know about them. I've bought a lot of stuff from them.
     
  11. DaveW

    DaveW Active Member Licensed User

    Hi Andrew,

    I have got the DLL working except for one small (really big) problem. I have to redim the structures/arrays inside the function to take the data I am reading in from an XML file. I can do the redim OK and I can read the data - debugging messages in the DLL show that they are the right size and full of data when the function finishes. However when the function returns to B4PPC the structures are all empty. Another structure/array that does not get redimed does return it's data OK so I know some of it is working. Could it be that the redim is breaking the link to the passed structure in some way? Do you have any suggestions to get over this problem?

    Regards,
    David.
     
  12. agraham

    agraham Expert Licensed User

    It almost certainly is (arrays are reference types - read your new book :) ) and I'm sure there is a solution but some of your explanation is bit too fuzzy to let me understand what is happening I'm afraid. Is the "function" within Basic4ppc or the library and by ReDim do you mean a Basic4pcc Dim in a Sub or a C# "array = new somtetype[somesize];"

    If you post the code for the library function and the Basic4ppc code line that you use to call it I'll sort it for you.
     
  13. DaveW

    DaveW Active Member Licensed User

    Sorry, still waiting for Father Christmas to visit ;)

    Code is:

    in B4PPC
    Code:
    'global
    Public CompBaseData(0,0As single

    'sub
    xmlread.OpenComp(name,main.CompInfo(),CompBaseData())
    in DLL
    Code:
    public void OpenComp(String filename, string[] CompInfo, float[,] CompBaseData)
    .....
    // this 
    bit resizes the structure/array
    float[,] temp = new float[Cols,Rows];
    System.Array.Copy(CompBaseData,temp,CompBaseData.Length);
    CompBaseData = temp;
    //remaining code fills the 
    array with data (works within the function)
    I hope that this is more understandable :)
     
  14. agraham

    agraham Expert Licensed User

    Yup, it is. The library gets passed a reference to the array, effectively its address in memory, in a local parameter variable held on the call stack. Using this reference you can update the data as seen by Basic4ppc as you both hold the same reference. By reassigning the library parameter variable that holds the reference you are assigning a new reference to a new array in a different area of memory to a local variable on the stack which gets lost when the method returns. You need to pass that new reference back to Basic4ppc and assign it to an array variable for it to be able to use it.


    Code:
    'global
    Public CompBaseData(0,0As single

    'sub
    CompBaseData() = xmlread.OpenComp(name,main.CompInfo(),CompBaseData())

    public void OpenComp(String filename, string[] CompInfo, float[,] CompBaseData)
    .....
    // this 
    bit resizes the structure/array
    float[,] temp = new float[Cols,Rows];
    System.Array.Copy(CompBaseData,temp,CompBaseData.Length);
      ...
    return temp;
     
  15. DaveW

    DaveW Active Member Licensed User

    I'm afraid that there is a bit more complication - there are actually 4 structures that get passed and resized (I only showed one for clarity). I would need do something like:

    Return temp1, temp2, temp3, temp4;

    but that won't work either of course as there can only be one return value :(
     
  16. agraham

    agraham Expert Licensed User

    I expected you to come back with that one :) Use some globals in the library and return the array references with properties.

    Code:
    Basic4Ppc
    Dim Array1 etc
    ...

    Library.myfunc(stuff)
    Array1 = Library.Array1
     etc.


    DLL

    private float[,] array1;
    private float[,] array2;
    private float[,] array2;


    public void myfunc(stuff)
    {
      array1 = new float[da-da]
      array2 = etc.
       
    do stuff
    }

    public float[,] Array1
    { get { return array1; } }

    etc.
     
  17. DaveW

    DaveW Active Member Licensed User

    I cheated - and took my usual crude but effective approach. I split the DLL function into 2, one to just get the size data, resized the structures in B4PPC and then read the data into the correctly sized arrays in a second function. It works and in combination with the ArrayToImage function, cuts the process time from 233 seconds to 30 seconds! :sign0060:

    I will try to use your more elegant solution though.

    Thanks for all the support! :sign0098:
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice