Avatar billede ghorfraq Nybegynder
02. december 2003 - 10:35 Der er 10 kommentarer og
1 løsning

Unmanaged Array

Jeg ønsker at sende et integerArray til en c++ dll-fil.

Her er mit import eksempel:
[DllImport("cfrontWrapper.dll")]
public static extern bool setCurrentKey([MarshalAs(UnmanagedType.I4)]int hTable, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_I4)] int[] ar);

Jeg får følgende fejl ved kompilering:
C:\MyWork\CSharp\Tidsur\functionTest\CFrontWrapper.cs(225): The name 'VT_I4' does not exist in the class or namespace 'functionTest.CFrontWrapper'
Avatar billede ghorfraq Nybegynder
02. december 2003 - 11:15 #1
Lykkedes med følgende kode.

public static extern bool setCurrentKey([MarshalAs(UnmanagedType.I4)]int hTable, [MarshalAs(UnmanagedType.LPArray)] int[] ar);       

Men er der så nogle der istedet ved hvordan man modtager en long* returværdi?
Altså den skal modtages i c# .NET - Marshalling
Avatar billede ghorfraq Nybegynder
02. december 2003 - 11:16 #2
leger ligenu med returværdi af typen IntPtr
Avatar billede arne_v Ekspert
02. december 2003 - 15:22 #3
C/C++ long (med gængse windows compilere) = C# int
Avatar billede ghorfraq Nybegynder
03. december 2003 - 07:40 #4
ved godt hvilken datatype jeg skal benytte. Problemet ligger mere i at assigne hukommelsesadressen til .NET variablen
Avatar billede ghorfraq Nybegynder
03. december 2003 - 07:58 #5
PointerVærdien ligges i en IntPtr-type som er en pointer. Dernæst skal man med Marshal oversætte den til en type som .NET understøtter.
Ved returnering af char* kan følgende gøres i .NET:
    IntPtr ptr = getFieldDataString(hTable, hRec, fieldName);
    string data = Marshal.PtrToStringAnsi(ptr);

Jeg kan bare ikke lige finde en tilsvarende løsning for pointer til arrays (long*)
Avatar billede ghorfraq Nybegynder
03. december 2003 - 07:59 #6
getFieldDataString er den eksterne metode kaldt i en DLL. Den returnerer da char*
Avatar billede ghorfraq Nybegynder
03. december 2003 - 08:04 #7
Det lykkedes med følgende kode.
unsafe
{
    int *arr;// = new int[3];
    IntPtr ptr = getCurrentKey(hTable);
    arr = (int*)ptr.ToPointer();

    for (int i = 0; i < 3; i++)
    {
    Console.WriteLine("KEY : " + arr[i].ToString());
    }
}
Avatar billede arne_v Ekspert
03. december 2003 - 11:11 #8
Du kan faktisk godt erklære din dll funktion til at returnere
en pointer.

static long result[] = { 1, 2, 3 };

DOTNET_API long *onetwothree(void)
{
    return result;
}

using System;
using System.Runtime.InteropServices;

class MainClass
{
    [DllImport("D:\\IDEProjects\\VisualStudio\\DotNET\\Release\\DotNET.dll")]
    private static extern int *onetwothree();
    public static void Main(string[] args)
    {
        unsafe
        {
            int *result = onetwothree();
            for(int i = 0; i < 3; i++) {
                Console.WriteLine(result[i]);
            }
        }
    }
}

virker !
Avatar billede ghorfraq Nybegynder
03. december 2003 - 11:14 #9
i princippet det smame som mit ovenstående kode. Bortset fra at jeg leder pointeren gennem datatypen IntPtr og derefter caster den til en int*
Avatar billede ghorfraq Nybegynder
03. december 2003 - 11:15 #10
smame = samme :)
Avatar billede arne_v Ekspert
03. december 2003 - 11:21 #11
Jep.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester