programming ADC11 with C#

Forum for discussing PicoLog
Post Reply
ferhan
User
User
Posts: 5
Joined: Tue Oct 30, 2007 10:44 am

programming ADC11 with C#

Post by ferhan »

I' trying to develope a project using C#. but I can't access the functions which take pointer kind of parameter. I use adc1132.dll. the other functions are OK. But pointer kind of parameter is a big poblem for me.
how can I declare the pointer in dll specification and in my C# project.
Also I want to know that:
Can't I use an array instead of pointer. I tried to do this but I couldn't. I dont know the thing that I made misteke..
I'm looking forward your replies...
thanks

markB
Site Admin
Site Admin
Posts: 83
Joined: Tue Mar 27, 2007 9:43 am
Location: Cambridgeshire,UK

Post by markB »

If the pointer is a pointer to an array, simply passing a managed array will do the job. The Marshaler will do all of the interop work for you.

If the pointer is a pointer to a variable that is set by the function, try declaring ref or out paramters.

Just having a quick look at the ADC11 api, I dont think that you will need to have any unsafe code at all. If you are having problems with any particular function, can you let us know which one and post your c# declaration so that we can see where you are going wrong.
Regards

Mark

ferhan
User
User
Posts: 5
Joined: Tue Oct 30, 2007 10:44 am

here is my project

Post by ferhan »

Hi and thanks for your reply

This is my class for ADC1132.dll declarations.

using System;
using System.Runtime.InteropServices;
namespace usbbaglanti
{
class usbcom
{
[DllImport("adc1132.dll", SetLastError = true)]
public static extern bool adc11_open_unit(int port, int product);
[DllImport("adc1132.dll", SetLastError = true)]
public static extern int adc11_get_unit_info([MarshalAs(UnmanagedType.LPArray)] string[] str, int str_lth, int line, int port);
[DllImport("adc1132.dll", SetLastError = true)]
public static extern void adc11_close_unit(int port);
[DllImport("adc1132.dll", SetLastError = true)]
public static extern int adc11_get_value(int channel);
[DllImport("adc1132.dll", SetLastError = true)]
public static extern int adc11_get_driver_version();
[DllImport("adc1132.dll", SetLastError = true)]
public static extern ulong adc11_get_values([MarshalAs(UnmanagedType.LPArray)]ushort[] values, ulong no_of_values);
}
}


And this is my project.


string[] info=new string[80];
try
{
if (usbbaglanti.usbcom.adc11_open_unit(101, 111))
{
MessageBox.Show("The unit opened successfully");
for (int a = 0; a < 4; a++)
{
if (usbbaglanti.usbcom.adc11_get_unit_info(info, info.Length, a, 101) > 0)
MessageBox.Show(info.ToString());
}
}
else
{
MessageBox.Show("The unit couldn't opened..");
if (usbbaglanti.usbcom.adc11_get_unit_info(info, info.Length, 0, 101) > 0)
MessageBox.Show(info.ToString());
}
}

catch (Exception ee)
{
MessageBox.Show(ee.Message.ToString());

}
}



I’m beginner :( .I couldn’t take the return value function adc11_get_unit_info.when I sent “infoâ€

markB
Site Admin
Site Admin
Posts: 83
Joined: Tue Mar 27, 2007 9:43 am
Location: Cambridgeshire,UK

Post by markB »

I've modified some of your declarations:

Code: Select all

[DllImport("adc1132.dll", SetLastError = true)]
public static extern bool adc11_open_unit(short port, short product);

[DllImport("adc1132.dll", SetLastError = true)]
public static extern int adc11_get_unit_info(StringBuilder str, short str_lth, short line, short port);

[DllImport("adc1132.dll", SetLastError = true)]
public static extern void adc11_close_unit(short port);
    
[DllImport("adc1132.dll", SetLastError = true)]
public static extern int adc11_get_value(short channel);
    
[DllImport("adc1132.dll", SetLastError = true)]
public static extern int adc11_get_driver_version();
    
[DllImport("adc1132.dll", SetLastError = true)]
public static extern ulong adc11_get_values(ushort[] values, uint no_of_values);
  • You need to be careful with your native and managed types. ints and shorts are different sizes and so you cant simply interchange them.

    I've used a StringBuilder to marshal c style char arrays into managed strings.

    You dont need to use attribute to override the default marshalling unless you are going to something out of the ordinary.
Your new program should look as follows:

Code: Select all

      StringBuilder info = new StringBuilder(256);
      try
      {
        if (usbbaglanti.usbcom.adc11_open_unit(101, 111))
        {
          MessageBox.Show("The unit opened successfully");

          for (short a = 0; a < 4; a++)
          {
            if (usbbaglanti.usbcom.adc11_get_unit_info(info, (short) info.Length, a, 101) > 0)
              MessageBox.Show(info.ToString());
            
          }
        }
        else
        {
          MessageBox.Show("The unit couldn't opened..");

          if (usbbaglanti.usbcom.adc11_get_unit_info(info, (short) info.Length, 0, 101) > 0)
            MessageBox.Show(info.ToString());
        }
      }
      catch (Exception ee)
      {
        MessageBox.Show(ee.Message.ToString());
      }
Regards

Mark

ferhan
User
User
Posts: 5
Joined: Tue Oct 30, 2007 10:44 am

thanks

Post by ferhan »

thanks for your help markB...

the problem solved. It works succesfully.

thanks a lot..

ffff
Newbie
Posts: 1
Joined: Wed Aug 08, 2007 10:51 am

adc11_set_interval() and pointer!!!

Post by ffff »

Hi mark,
I have the same problem with ferhan. you solved that problem using 'StringBuilder' class. no problem, because that pointer's kind is string. but in another function this is error. because pointers kinds cannot always be a string.
for example
adc11_set_interval. I want to collect data for 50000 us from 2 channels(Ch1 and Ch3).

here is my dll declaration

[DllImport("adc1132.dll", SetLastError = true)]
public static extern ulong adc11_set_interval(ulong us_for_block, ulong ideal_no_of_samples, [MarshalAs(UnmanagedType.LPArray)] short[] channels, short no_of_channels);

and this is function call in my project.

public static ulong BUFFER_SIZE= 1000;
public long [] times= new long[BUFFER_SIZE];
public ushort[] values = new ushort[Convert.ToInt16(BUFFER_SIZE) * MAX_CHANNELS_AT_ONCE];
ulong actual;
short [] channels = { 1, 3};
short no_of_channels = 2;
actual = bitir.usbcon.adc11_set_interval(100000, BUFFER_SIZE, channels[0], no_of_channels);
Console.WriteLine(actual.ToString());


For the pointer, I used an array which's kind of short. I sent the first address to function to start first adress then second, then etc.
but when I run the project, I see an error message like that

Error 1 The best overloaded method match for 'bitir.usbcon.adc11_set_interval(ulong, ulong, short[], short)' has some invalid arguments

Error 2 Argument '3': cannot convert from 'short' to 'short[]'

And something else. If I send "channels" (not channels[0]) the return value isn't as I want. I want 50000us return value but is sends me that.
**************************
8589934592
**************************

If you can help me I'll be happy.
Best regards..

markB
Site Admin
Site Admin
Posts: 83
Joined: Tue Mar 27, 2007 9:43 am
Location: Cambridgeshire,UK

Post by markB »

You need to be careful with your native and managed types. ints and shorts are different sizes and so you cant simply interchange them.
.
.

You dont need to use attribute to override the default marshalling unless you are going to something out of the ordinary.
You therefore need to define and use the function as follows:

Code: Select all

        
[DllImport("adc1132.dll")]
public static extern uint adc11_set_interval(uint us_for_block, uint ideal_no_of_samples, short[] channels, short no_of_channels); 



uint BUFFER_SIZE = 1000;
short[] channels = { 1, 3 };
uint actual = usbbaglanti.usbcom.adc11_set_interval(100000, BUFFER_SIZE, channels, (short) channels.Length);
I cannot repeat the invalid return value problem. My guess is that the incorrect declaration and usages could be passing undesired parameters to the dll.
Regards

Mark

Post Reply