//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
// To jest główny plik projektu dla projektu aplikacji VC++, 
// wygenerowany przy użyciu Application Wizarda.

#include "stdafx.h"

#using <mscorlib.dll>
#include <tchar.h>

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Text;


namespace Native 
{
	[DllImport("unmanaged")]
	extern "C" int AddInteger(int a, int b);
	[DllImport("unmanaged")]
	extern "C" int StringLength(String* str);
	[DllImport("unmanaged", CharSet=CharSet::Unicode)]
	extern "C" int UnicodeStringLength(String* str);

	[DllImport("unmanaged.dll")]
	extern "C" unsigned char ByteFunc(unsigned char a);
	[DllImport("unmanaged.dll")]
	extern "C" short ShortFunc(short a);
	[DllImport("unmanaged.dll")]
	extern "C" unsigned short WordFunc(short a);
	[DllImport("unmanaged.dll")]
	extern "C" unsigned int UintFunc(unsigned int a);
	[DllImport("unmanaged.dll")]
	extern "C" int LongFunc(int a);
	[DllImport("unmanaged.dll")]
	extern "C" unsigned int UnsignedLongFunc(unsigned int a);
	[DllImport("unmanaged.dll")]
	extern "C" char CharFunc(char a);
	[DllImport("unmanaged.dll")]
	extern "C" float FloatFunc(float a);
	[DllImport("unmanaged.dll")]
	extern "C" double DoubleFunc(double a);

	[DllImport("unmanaged.dll")]
	extern "C" void ByteOutOutFunc(unsigned char a, unsigned char* o);
	[DllImport("unmanaged.dll")]
	extern "C" void ShortOutFunc(short a, short* o);
	[DllImport("unmanaged.dll")]
	extern "C" void WordOutFunc(unsigned short a, unsigned short* o);
	[DllImport("unmanaged.dll")]
	extern "C" void IntOutFunc(int a, int* o);
	[DllImport("unmanaged.dll")]
	extern "C" void UintOutFunc(unsigned int a, unsigned int* o);
	[DllImport("unmanaged.dll")]
	extern "C" void LongOutFunc(int a, int* o);
	[DllImport("unmanaged.dll")]
	extern "C" void UnsignedLongOutFunc(unsigned int a, unsigned int* o);
	[DllImport("unmanaged.dll")]
	extern "C" void CharOutFunc(char a, char* o);
	[DllImport("unmanaged.dll")]
	extern "C" void FloatOutFunc(float a, float* o);
	[DllImport("unmanaged.dll")]
	extern "C" void DoubleOutFunc(double a, double* o);
	[DllImport("unmanaged.dll")]
	extern "C" String* ConcatString(String *a, String *b);

	[DllImport("unmanaged.dll", CharSet=CharSet::Unicode)]
	extern "C" String* ConcatUnicodeString(String *a, String *b);

	[DllImport("unmanaged.dll")]
	extern "C" void ConcatOutString(String *a, String *b, StringBuilder *o);
}

int _tmain(void)
{
    Console::WriteLine(S"Witaj świecie!");
	int retInt = Native::AddInteger(1, 2);
	Console::WriteLine(S"Wynik AddInteger: {0}", __box(retInt));

	String *str = S"To jest test";
	int retLength = Native::StringLength(str);
	Console::WriteLine(S"Długość ciągu: {0}", __box(retLength));

	retLength = Native::UnicodeStringLength(str);
	Console::WriteLine(S"Długość ciągu Unicode: {0}", __box(retLength));

	unsigned char byteRet = Native::ByteFunc(10);
	short shortRet = Native::ShortFunc(10);
	unsigned short ushortRet = Native::WordFunc(10);
	unsigned int uintRet = Native::UintFunc(10);
	int longRet = Native::LongFunc(10);
	unsigned int ulongRet = Native::UnsignedLongFunc(10);
	char charRet = Native::CharFunc((char)10);
	float floatRet = Native::FloatFunc(10);
	double doubleRet = Native::DoubleFunc(10);

	Native::ByteOutOutFunc(20,&byteRet);
	Native::ShortOutFunc(20, &shortRet);
	Native::WordOutFunc(20, &ushortRet);
	Native::IntOutFunc(20, &longRet);
	Native::UintOutFunc(20, &uintRet);
	Native::LongOutFunc(20, &longRet);
	Native::UnsignedLongOutFunc(20, &ulongRet);
	Native::CharOutFunc((char)20, &charRet);
	Native::FloatOutFunc(20, &floatRet);
	Native::DoubleOutFunc(20, &doubleRet);

	String *a = S"To jest ";
	String *b = S"test";
	String *result = Native::ConcatString(a, b);
	Console::WriteLine("Wynik połączenia ciągów: {0}", result);

	result = Native::ConcatUnicodeString(a, b);
	Console::WriteLine("Wynik połączenia ciągów Unicode: {0}", result);

	StringBuilder *sbr = new StringBuilder(128);
	Native::ConcatOutString(a, b, sbr);
	Console::WriteLine("Po usunięciu ciągu: {0}", sbr);

    return 0;
}