Skip to content

Instantly share code, notes, and snippets.

@erichschroeter
Created April 25, 2014 15:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erichschroeter/11292640 to your computer and use it in GitHub Desktop.
Save erichschroeter/11292640 to your computer and use it in GitHub Desktop.
Simple marshalling hello world with nested struct.
#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;
}
#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 */
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);
}
}
Joe Schmoe 1234567890 0987654321
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