Laden...

Interop + Strukturen

Erstellt von Tankian vor 18 Jahren Letzter Beitrag vor 18 Jahren 2.008 Views
T
Tankian Themenstarter:in
81 Beiträge seit 2004
vor 18 Jahren
Interop + Strukturen

Hallo,

hab heute vergeblich versucht einen Wrapper um eine C-API zu basteln, habe irgendwie Probleme
beim Marshalling schätze ich mal, da die Werte vollkommener Blödsinn sind, aber keine Exception
oder ähnliches auftritt.

Ich hoffe mal, ihr könnt C soweit, das ihr folgenden Code versteht, dürfte aber eigentlich kein Problem sein.


#include <stdlib.h>
#include <stdio.h>

typedef struct {
	int pay;
	int hours_of_work;
} Employee;

Employee* createEmployee(int pay, int hours_of_work) {
	Employee* employee = (Employee*)malloc(sizeof(Employee));
	
	employee->pay = pay;
	employee->hours_of_work = hours_of_work;
	
	printf("pay:  %i \n", pay);
	printf("work: %i \n", hours_of_work);
	
	return employee;
}

void deleteEmployee(Employee* employee) {
	free(employee);
}

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
internal struct Employee 
{
	public int Pay;
	public int HoursOfWork;
}

public class AppEntry 
{
	[DllImport("Employee", EntryPoint="createEmployee")]
	[return: MarshalAs(UnmanagedType.LPStruct)]
	private static extern Employee CreateEmployee(int pay, int hoursOfWork);
	
	[DllImport("Employee", EntryPoint="deleteEmployee")]
	private static extern void DeleteEmployee([MarshalAs(UnmanagedType.LPStruct)] Employee employee);

	public static void Main() {
		Employee e = CreateEmployee(5, 5);
		
		Console.WriteLine("Pay:         {0}", e.Pay);
		Console.WriteLine("HoursOfWork: {0}", e.HoursOfWork);
		
		DeleteEmployee(e);
	}
}

Ausgabe:
pay: -16805528
work: 5
Pay: 154019616
HoursOfWork: 153581768

gewünschte Ausgabe:
pay: 5
work: 5
Pay: 5
HoursOfWork: 5

Wo könnte der Fehler liegen?

Schonmal danke.

X
2.051 Beiträge seit 2004
vor 18 Jahren
 
using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
	
	[StructLayout(LayoutKind.Sequential)]
	internal struct Employee
	{
		public int Pay;
		public int HoursOfWork;
	}

	public class AppEntry
	{
		[DllImport("Win32Test.dll", EntryPoint="createEmployee")]
		private static extern IntPtr CreateEmployee(int pay, int hoursOfWork);
    
		[DllImport("Win32Test.dll", EntryPoint="deleteEmployee")]
		private static extern void DeleteEmployee(IntPtr employee);

		public static void Main() 
		{
			IntPtr pe = CreateEmployee(5, 5);
			Employee e = (Employee)Marshal.PtrToStructure(pe, typeof(Employee));
        
			Console.WriteLine("Pay:         {0}", e.Pay);
			Console.WriteLine("HoursOfWork: {0}", e.HoursOfWork);
        
			DeleteEmployee(pe);
			Console.Read();
		}
	}
}

T
Tankian Themenstarter:in
81 Beiträge seit 2004
vor 18 Jahren

Hallo,

danke hat bestens funktioniert. Aber warum meine Version nicht, bzw wie
wendet man [MarshalAs(UnmanagedType.LPStruct)] denn sonst an?

grüße

X
2.051 Beiträge seit 2004
vor 18 Jahren

du kannst das auch so machen:

 
	[StructLayout(LayoutKind.Sequential)]
	internal class Employee   // <<<<<<<<<<<<<<<<<<<<<<
	{
		public int Pay;
		public int HoursOfWork;
	}

	public class AppEntry
	{
		[DllImport("Employee.dll", EntryPoint="createEmployee")]
		[return: MarshalAs(UnmanagedType.LPStruct)]   // <<<<<<<<<<<<<
		private static extern Employee CreateEmployee(int pay, int hoursOfWork);

...

allerdings gibt es dann problemme beim löschen des objektes.