[C#] structs met arrays naar DLL via pointer probleem

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • redtiger
  • Registratie: Juni 2007
  • Laatst online: 24-10-2023
Hallo,

Ik ben eigenlijk meer C programmeerder maar wil nu toch met C# beginnen. Ik heb een CAN naar USB adapter van NI die ik graag wil aansturen.
Het probleem is dat de functie Read een pointer naar een struct verwacht.

Functie aanroep:
C#:
1
2
        [DllImport("nican.dll")]
        public static extern unsafe UInt32 ncRead(UInt32 objHandle, UInt32 dataSize, UInt32* DataPtr);

De pointer naar DataPtr geeft de locatie aan naar de struct waar de data heengeschreven moet worden.
Hier dient dan een struct te staan:

Deze struct moet er als volgt uitzien:
C#:
1
2
3
4
5
6
7
8
9
        [StructLayout(LayoutKind.Sequential)]
        public struct canFrames{
            public byte FrameType;
            public UInt32 ArbitrationId;
            public System.Runtime.InteropServices.ComTypes.FILETIME Timestamp;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public Byte[] Data;
            public Byte DataLenght;
        }


Functie aanroep:
C#:
1
2
3
4
5
            canFrames CanData = new canFrames();
            UInt32 ReturnCan;
            [..]
            InitializeComponent();            
            ReturnCan = ncRead(handle, 8, CanData);


Hier krijg ik een error "Cannot convert ..."

Wat ik niet snap is hoe ik nu deze struct aan de functie meegeef?
Alvast bedankt.

Acties:
  • 0 Henk 'm!

  • Razr
  • Registratie: September 2005
  • Niet online
Ik snap niet precies wat er nou precies verwacht wordt door de ncRead();. Kun je de hele foutmelding niet is posten (die van "Cannot convert..").

Acties:
  • 0 Henk 'm!

  • redtiger
  • Registratie: Juni 2007
  • Laatst online: 24-10-2023
de error is:

Error 1 The best overloaded method match for 'CAN.ncRead(uint, uint, uint*)' has some invalid arguments
Error 2 Argument '3': cannot convert from 'CAN.canFrames' to 'uint*'

wat ik denk dat de functie verwacht is
struct data {
[..]
}

ncRead(x,y,struct data *p)

ncRead(x,y, &Data);

maarja da's c++ en ik wil graag naar c#

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

je candata struct zit op de managed heap (ie, relocatable etc). Ik denk dat je een fixed() statement nodig hebt.

Je krijgt dan iets als dit (losse hand)
C#:
1
2
3
4
5
6
7
unsafe void CallRead(uint x, uint y, CanData data)
{
  fixed(CanData *ptr = &data)
  {
    ncRead(x, y, (uint*)ptr);
  }
}

[ Voor 1% gewijzigd door MLM op 22-02-2009 12:36 . Reden: missende tag ]

-niks-


Acties:
  • 0 Henk 'm!

  • redtiger
  • Registratie: Juni 2007
  • Laatst online: 24-10-2023
oke, wat ik nu heb is:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        [StructLayout(LayoutKind.Sequential)]
        public struct canFrames
        {
            public byte FrameType;
            public UInt32 ArbitrationId;
            public System.Runtime.InteropServices.ComTypes.FILETIME Timestamp;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public Byte[] Data;
            public Byte DataLenght;
        }

        [DllImport("nican.dll")]
        public static extern unsafe Int32 ncRead(UInt32 objHandle, UInt32 dataSize, UInt32* data);

        CAN.canFrames CanData = new CAN.canFrames(); 

        unsafe Int32 CallRead(uint objHandle, uint dataSize, CanData data)
        {
            fixed (UInt32* ptr = &data)
            {
                Int32 status;
                status = CAN.ncRead(objHandle, dataSize, (uint*)ptr);
                return status;
            }
        }


Kan je misschien nog zeggen hoe ik de functie CallRead nu aanroep?
Als ik
C#:
1
            CallRead(handle, 8, CanData);

doe krijg ik een error
Error 1 The best overloaded method match for 'DC_Load.Form1.CallRead(uint, uint, CanData)' has some invalid arguments
Error 2 Argument '3': cannot convert from 'CAN.canFrames' to 'CanData'

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 21:05

Haan

dotnetter

Moet deze regel
C#:
1
unsafe Int32 CallRead(uint objHandle, uint dataSize, CanData data)

niet zo zijn?
C#:
1
unsafe Int32 CallRead(uint objHandle, uint dataSize, CAN.canFrames data)


Dat is in ieder geval wat de error zegt: jij zegt dat CallRead een CanData als type mee moet krijgen, maar je geeft een canFrames type mee. Dus je moet of de CallRead methode aanpassen, of je moet geen canFrames type meegeven, maar een CanData type.

[ Voor 38% gewijzigd door Haan op 22-02-2009 13:35 ]

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • redtiger
  • Registratie: Juni 2007
  • Laatst online: 24-10-2023
@Haan; zo heb ik het nu idd ook en dan heb ik idd geval tijdens het compileren geen errors meer. De functie werkt alleen nog niet en dat komt omdat de struct zoals ie nu naar binnen gaat niet goed overdragen wordt.
Of het ligt aan de pointer of het ligt aan de opbouw in het geheugen.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
       [StructLayout(LayoutKind.Explicit, size= 78)]
        public struct canFrames
        {
            [FieldOffset(0)]
            public byte FrameType;
            [FieldOffset(1)]
            public UInt32 ArbitrationId;
            [FieldOffset(5)]
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public Byte[] Data;
            [FieldOffset(69)]
            public Byte DataLenght;
            [FieldOffset(70)]
            public System.Runtime.InteropServices.ComTypes.FILETIME Timestamp;
        }


Klopt dit? Ik heb het aantal bytes vanaf de start als offset genomen en het totaal als size aangegeven?

//Edit
Bij het compileren geeft ie een error:

Het type canFrames uit de assembly DC Load, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null kan niet worden geladen omdat het bij de offset 5 een objectveld bevat dat onjuist is uitgelijnd of dat wordt overlapt door een veld dat geen object is.

[ Voor 13% gewijzigd door redtiger op 22-02-2009 13:55 ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 20:04
Waarom wil je hier eigenlijk C# voor gebruiken? Het is duidelijk een lib die daarvoor niet echt bedoeld is.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • redtiger
  • Registratie: Juni 2007
  • Laatst online: 24-10-2023
Tsja daar ben ik nu wel achter gekomen. Ik wil graag beginnen met C# en de software die ik tot nu toe gebruikte voor deze adapter was gemaakt in labview, maar dat word al snel onoverzichtelijk vandaar.
Inmiddels komt er wel iets in de struct te staan, alleen nog niet het juiste, hopelijk wat kleins.
Pagina: 1