.NET Framework Developer's Guide
PinvokeLib.dll
The following code defines the library functions provided by Pinvoke.dll. Many samples described in this section call this library.
[C#]
#include "stdafx.h" #include "PinvokeLib.h" #include <objbase.h> #include <stdio.h> BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } // This is the constructor of a class that has been exported. CTestClass::CTestClass() { m_member = 1; } int CTestClass::DoSomething( int i ) { return i*i + m_member; } extern "C" PINVOKELIB_API CTestClass* CreateTestClass() { return new CTestClass(); } extern "C" PINVOKELIB_API void DeleteTestClass( CTestClass* instance ) { delete instance; } //****************************************************************** extern "C" PINVOKELIB_API int TestArrayOfInts( int* pArray, int size ) { int result = 0; for( int i = 0; i < size; i++ ) { result += pArray[ i ]; pArray[ i ] += 100; } return result; } //****************************************************************** extern "C" PINVOKELIB_API int TestRefArrayOfInts( int** ppArray, int* pSize ) { int result = 0; // CoTaskMemAlloc must be used instead of the new operator // because code on the managed side will call Marshal.FreeCoTaskMem // to free this memory. int* newArray = (int*)CoTaskMemAlloc( sizeof(int) * 5 ); for( int i = 0; i < *pSize; i++ ) { result += (*ppArray)[ i ]; } for( int j = 0; j < 5; j++ ) { newArray[ j ] = (*ppArray)[ j ] + 100; } CoTaskMemFree( *ppArray ); *ppArray = newArray; *pSize = 5; return result; } //****************************************************************** extern "C" PINVOKELIB_API int TestMatrixOfInts( int pMatrix[][COL_DIM], int row ) { int result = 0; for( int i = 0; i < row; i++ ) { for( int j = 0; j < COL_DIM; j++ ) { result += pMatrix[ i ][ j ]; pMatrix[ i ][ j ] += 100; } } return result; } //****************************************************************** extern "C" PINVOKELIB_API int TestArrayOfStrings( char* ppStrArray[], int size ) { int result = 0; char* temp; for( int i = 0; i < size; i++ ) { result += strlen( ppStrArray[ i ] ); temp = (char*)CoTaskMemAlloc( sizeof(char) * 10 ); strcpy( temp, "123456789" ); // CoTaskMemFree must be used instead of delete to free memory. CoTaskMemFree( ppStrArray[ i ] ); ppStrArray[ i ] = temp; } return result; } //****************************************************************** extern "C" PINVOKELIB_API int TestArrayOfStructs( MYPOINT* pPointArray, int size ) { int result = 0; MYPOINT* pCur = pPointArray; for( int i = 0; i < size; i++ ) { result += pCur->x + pCur->y; pCur->y = 0; pCur++; } return result; } //****************************************************************** extern "C" PINVOKELIB_API int TestArrayOfStructs2( MYPERSON* pPersonArray, int size ) { int result = 0; MYPERSON* pCur = pPersonArray; char* temp; for( int i = 0; i < size; i++ ) { result += strlen( pCur->first ) + strlen( pCur->last ); temp = (char*)CoTaskMemAlloc( sizeof(char) * ( strlen( pCur->last ) + 2 )); strcpy( temp, "Mc" ); strcat( temp, pCur->last ); // CoTaskMemFree must be used instead of delete to free memory. CoTaskMemFree( pCur->last ); pCur->last = temp; pCur++; } return result; } //****************************************************************** extern "C" PINVOKELIB_API int TestStructInStruct( MYPERSON2* pPerson2 ) { char* temp = (char*)CoTaskMemAlloc( sizeof(char) * ( strlen( pPerson2->person->last ) + 2 )); strcpy( temp, "Mc" ); strcat( temp, pPerson2->person->last ); CoTaskMemFree( pPerson2->person->last ); pPerson2->person->last = temp; return pPerson2->age; } //****************************************************************** extern "C" PINVOKELIB_API void TestStructInStruct3( MYPERSON3 person3 ) { printf( "\n\nperson passed by value:\n" ); printf( "first = %s last = %s age = %i\n\n", person3.person.first, person3.person.last, person3.age ); } //********************************************************************* extern "C" PINVOKELIB_API void TestUnion( MYUNION u, int type ) { if(( type != 1 ) && ( type != 2 )) return; if( type == 1 ) printf( "\n\ninteger passed: %i", u.i ); else if( type == 2 ) printf( "\n\ndouble passed: %f", u.d ); } //****************************************************************** extern "C" PINVOKELIB_API void TestUnion2( MYUNION2 u, int type ) { if(( type != 1 ) && ( type != 2 )) return; if( type == 1 ) printf( "\n\ninteger passed: %i", u.i ); else if( type == 2 ) printf( "\n\nstring passed: %s", u.str ); } //****************************************************************** extern "C" PINVOKELIB_API void TestCallBack( FPTR pf, int value ) { printf( "\nReceived value: %i", value ); printf( "\nPassing to callback..." ); bool res = (*pf)(value); if( res ) printf( "Callback returned true.\n" ); else printf( "Callback returned false.\n" ); } //****************************************************************** extern "C" PINVOKELIB_API void TestCallBack2( FPTR2 pf2, char* value ) { printf( "\nReceived value: %s", value ); printf( "\nPassing to callback..." ); bool res = (*pf2)(value); if( res ) printf( "Callback2 returned true.\n" ); else printf( "Callback2 returned false.\n" ); } //****************************************************************** extern "C" PINVOKELIB_API void TestStringInStruct( MYSTRSTRUCT* pStruct ) { wprintf( L"\nUnicode buffer content: %s\n", pStruct->buffer ); // Assuming that the buffer is big enough. wcscat( pStruct->buffer, L"++" ); } //****************************************************************** extern "C" PINVOKELIB_API void TestStringInStructAnsi( MYSTRSTRUCT2* pStruct ) { printf( "\nAnsi buffer content: %s\n", pStruct->buffer ); // Assuming that the buffer is big enough. strcat( pStruct->buffer, "++" ); } //****************************************************************** extern "C" PINVOKELIB_API void TestOutArrayOfStructs( int* pSize, MYSTRSTRUCT2** ppStruct ) { const int cArraySize = 5; *pSize = cArraySize; *ppStruct = (MYSTRSTRUCT2*)CoTaskMemAlloc( cArraySize * sizeof( MYSTRSTRUCT2 )); MYSTRSTRUCT2* pCurStruct = *ppStruct; char* buffer; for( int i = 0; i < cArraySize; i++, pCurStruct++ ) { pCurStruct->size = i; buffer = (char*)CoTaskMemAlloc( 4 ); strcpy( buffer, "***" ); pCurStruct->buffer = buffer; } } //************************************************************************ extern "C" PINVOKELIB_API char* TestStringAsResult() { char* result = (char*)CoTaskMemAlloc( 64 ); strcpy( result, "This is return value" ); return result; } //************************************************************************ extern "C" PINVOKELIB_API void SetData( DataType typ, void* object ) { switch( typ ) { case DT_I2: printf( "Short %i\n", *((short*)object) ); break; case DT_I4: printf( "Long %i\n", *((long*)object) ); break; case DT_R4: printf( "Float %f\n", *((float*)object) ); break; case DT_R8: printf( "Double %f\n", *((double*)object) ); break; case DT_STR: printf( "String %s\n", (char*)object ); break; default: printf( "Unknown type" ); break; } } //************************************************************************ extern "C" PINVOKELIB_API void TestArrayInStruct( MYARRAYSTRUCT* pStruct ) { pStruct->flag = true; pStruct->vals[ 0 ] += 100; pStruct->vals[ 1 ] += 100; pStruct->vals[ 2 ] += 100; } //************************************************************************