Created
April 25, 2014 15:02
-
-
Save erichschroeter/11292640 to your computer and use it in GitHub Desktop.
Simple marshalling hello world with nested struct.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <errno.h> | |
#include "hello.h" | |
static const char* get_field(char *line, int num) | |
{ | |
const char *tok; | |
for (tok = strtok(line, ","); tok && *tok; tok = strtok(NULL, ",\n")) { | |
if (!--num) | |
return tok; | |
} | |
return NULL; | |
} | |
static int parse_human(char *line, struct human *human) | |
{ | |
char *tmp = strdup(line); | |
const char *f; | |
printf("&human=%ld\n", human); | |
printf("&human->contact=%ld\n", human->contact); | |
f = get_field(tmp, 1); | |
printf("field 1='%s'\n", f); | |
memset(human->first, 0, sizeof(human->first)); | |
strcpy(human->first, f); | |
free(tmp); | |
tmp = strdup(line); | |
f = get_field(tmp, 2); | |
printf("field 2='%s'\n", f); | |
memset(human->last, 0, sizeof(human->last)); | |
strcpy(human->last, f); | |
free(tmp); | |
tmp = strdup(line); | |
f = get_field(tmp, 3); | |
printf("field 3='%s'\n", f); | |
memset(human->contact->cell, 0, sizeof(human->contact->cell)); | |
strcpy(human->contact->cell, f); | |
free(tmp); | |
tmp = strdup(line); | |
f = get_field(tmp, 4); | |
printf("field 4='%s'\n", f); | |
memset(human->contact->home, 0, sizeof(human->contact->home)); | |
strcpy(human->contact->home, f); | |
free(tmp); | |
return 0; | |
} | |
HELLOAPI int HELLOCALL say_hello(struct human *person) | |
{ | |
printf("Hello, %s %s\n", person->first, person->last); | |
if (person->contact && person->contact->cell) | |
printf("\tcell: %s\n", person->contact->cell); | |
if (person->contact && person->contact->home) | |
printf("\thome: %s\n", person->contact->home); | |
return 0; | |
} | |
HELLOAPI int HELLOCALL import_csv(char *path, struct human *person) | |
{ | |
int res; | |
FILE *csv; | |
char line[1024]; | |
if (person == NULL) { | |
return ENOMEM; | |
} | |
printf("parsing: '%s'\n", path); | |
csv = fopen(path, "r"); | |
if (csv == NULL) { | |
return errno; | |
} | |
fgets(line, 1024, csv); | |
printf("parsing: '%s'\n", line); | |
res = parse_human(line, person); | |
if (res != 0) { | |
return res; | |
} | |
fclose(csv); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ___HELLO_H | |
#define ___HELLO_H | |
#ifdef _WIN32 | |
//#ifdef par_EXPORTS | |
#define HELLOAPI __declspec(dllexport) | |
//#else | |
// #define HELLOAPI __declspec(dllimport) | |
//#endif | |
#define HELLOCALL __cdecl | |
#else | |
#define HELLOAPI | |
#define HELLOCALL | |
#endif | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
struct contact_info { | |
char cell[32]; | |
char home[32]; | |
}; | |
struct human { | |
char first[32]; | |
char last[32]; | |
struct contact_info *contact; | |
}; | |
HELLOAPI int HELLOCALL say_hello(struct human *person); | |
HELLOAPI int HELLOCALL import_csv(char *path, struct human *person); | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif /* ___HELLO_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Runtime.InteropServices; | |
namespace HelloApp | |
{ | |
class HelloLibrary | |
{ | |
[StructLayout(LayoutKind.Sequential)] | |
public struct contact_info | |
{ | |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] | |
public String cell; | |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] | |
public String home; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct human | |
{ | |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] | |
public String first; | |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] | |
public String last; | |
public IntPtr contact; | |
} | |
[DllImport("HelloLibrary.dll", CallingConvention = CallingConvention.Cdecl)] | |
public static extern int say_hello(ref human person); | |
[DllImport("HelloLibrary.dll", CallingConvention = CallingConvention.Cdecl)] | |
public static extern int import_csv([MarshalAs(UnmanagedType.LPStr)]String path, | |
ref human person); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Joe | Schmoe | 1234567890 | 0987654321 |
---|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Runtime.InteropServices; | |
namespace HelloApp | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
if (args.Length < 1) | |
{ | |
Console.WriteLine("Specify a CSV file."); | |
Environment.Exit(1); | |
} | |
//HelloLibrary.human person = new HelloLibrary.human(); | |
//person.first = "Joe"; | |
//person.last = "Schmoe"; | |
//HelloLibrary.contact_info info = new HelloLibrary.contact_info(); | |
//info.cell = "1234567890"; | |
//info.home = ""; | |
//IntPtr ptr1 = Marshal.AllocHGlobal(Marshal.SizeOf(info)); | |
//Marshal.StructureToPtr(info, ptr1, true); | |
//person.info = ptr1; | |
//HelloLibrary.say_hello(ref person); | |
HelloLibrary.human human = new HelloLibrary.human(); | |
human.contact = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HelloLibrary.contact_info))); | |
//human.contact = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HelloLibrary.contact_info))); | |
//HelloLibrary.contact_info contact = new HelloLibrary.contact_info(); | |
//IntPtr hptr = Marshal.AllocHGlobal(Marshal.SizeOf(human)); | |
//IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(contact)); | |
//IntPtr hptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HelloLibrary.human))); | |
//IntPtr iptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HelloLibrary.contact_info))); | |
//HelloLibrary.human human = (HelloLibrary.human)Marshal.PtrToStructure( | |
// hptr, typeof(HelloLibrary.human)); | |
HelloLibrary.contact_info contact = (HelloLibrary.contact_info)Marshal.PtrToStructure( | |
human.contact, typeof(HelloLibrary.contact_info)); | |
//Marshal.PtrToStructure(hptr, human); | |
//Marshal.PtrToStructure(iptr, contact); | |
//human.contact = iptr; | |
//Marshal.StructureToPtr(contact, human.contact, true); | |
Console.WriteLine("&human.contact={0}", human.contact); | |
//HelloLibrary.import_csv(args[0], ref hptr); | |
HelloLibrary.import_csv(args[0], ref human); | |
Console.WriteLine("first:'{0}'", human.first); | |
Console.WriteLine("last:'{0}'", human.last); | |
Console.WriteLine("cell:'{0}'", contact.cell); | |
Console.WriteLine("home:'{0}'", contact.home); | |
Console.Read(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment