PinvokeLib.dll

The following code defines the library functions provided by Pinvoke.dll. Many samples described in this section call this library.

#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;
}
//************************************************************************