Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The following code defines the library functions provided by Pinvoke.dll. Many samples described in this section call this library.
Example
// Interop.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "PinvokeLib.h"
#include <strsafe.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;
STRSAFE_LPWSTR temp;
for( int i = 0; i < size; i++ )
{
result += strlen( ppStrArray[ i ] );
temp = (STRSAFE_LPWSTR)CoTaskMemAlloc( sizeof(char) * 10 );
StringCchCopy( temp, sizeof(temp), (STRSAFE_LPWSTR)"123456789" );
// CoTaskMemFree must be used instead of delete to free memory.
CoTaskMemFree( ppStrArray[ i ] );
ppStrArray[ i ] = (char *) 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;
STRSAFE_LPWSTR temp;
for( int i = 0; i < size; i++ )
{
result += strlen( pCur->first ) + strlen( pCur->last );
temp = (STRSAFE_LPWSTR)CoTaskMemAlloc( sizeof(char) * ( strlen( pCur->last ) + 2 ));
StringCchCopy( temp, sizeof(temp), (STRSAFE_LPWSTR)"Mc" );
StringCbCat( temp, sizeof(temp), (STRSAFE_LPWSTR)pCur->last );
// CoTaskMemFree must be used instead of delete to free memory.
CoTaskMemFree( pCur->last );
pCur->last = (char *)temp;
pCur++;
}
return result;
}
//******************************************************************
extern "C" PINVOKELIB_API int TestStructInStruct( MYPERSON2* pPerson2 )
{
STRSAFE_LPWSTR temp = (STRSAFE_LPWSTR)CoTaskMemAlloc( sizeof(char) * ( strlen( pPerson2->person->last ) + 2 ));
StringCchCopy( temp, sizeof(temp), (STRSAFE_LPWSTR)"Mc" );
StringCbCat( temp, sizeof(temp), (STRSAFE_LPWSTR)pPerson2->person->last );
CoTaskMemFree( pPerson2->person->last );
pPerson2->person->last = (char *)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.
StringCbCat( pStruct->buffer, sizeof(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.
StringCbCat( (STRSAFE_LPWSTR) pStruct->buffer, sizeof(pStruct->buffer), (STRSAFE_LPWSTR)"++" );
}
//******************************************************************
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;
STRSAFE_LPWSTR buffer;
for( int i = 0; i < cArraySize; i++, pCurStruct++ )
{
pCurStruct->size = i;
buffer = (STRSAFE_LPWSTR)CoTaskMemAlloc( 4 );
StringCchCopy( buffer, sizeof(buffer), (STRSAFE_LPWSTR)"***" );
pCurStruct->buffer = (char *)buffer;
}
}
//************************************************************************
extern "C" PINVOKELIB_API char * TestStringAsResult()
{
STRSAFE_LPWSTR result = (STRSAFE_LPWSTR)CoTaskMemAlloc( 64 );
StringCchCopy( result, sizeof(result) , (STRSAFE_LPWSTR)"This is return value" );
return (char *) 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;
}
//************************************************************************
// PinvokeLib.h : The header file for the DLL application.
//
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the PINVOKELIB_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// PINVOKELIB_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
#ifdef PINVOKELIB_EXPORTS
#define PINVOKELIB_API __declspec(dllexport)
#else
#define PINVOKELIB_API __declspec(dllimport)
#endif
// This class is exported from the PinvokeLib.dll
class PINVOKELIB_API CTestClass
{
public:
CTestClass( void );
int DoSomething( int i );
private:
int m_member;
};
extern "C" PINVOKELIB_API CTestClass* CreateTestClass();
extern "C" PINVOKELIB_API void DeleteTestClass( CTestClass* instance );
//*************************************************************************************
extern "C" PINVOKELIB_API int TestArrayOfInts( int* pArray, int size );
extern "C" PINVOKELIB_API int TestRefArrayOfInts( int** ppArray, int* pSize );
const int COL_DIM = 5;
extern "C" PINVOKELIB_API int TestMatrixOfInts( int pMatrix[][COL_DIM], int row );
extern "C" PINVOKELIB_API int TestArrayOfStrings( char* ppStrArray[], int size );
//*************************************************************************************
typedef struct _MYPOINT
{
int x;
int y;
} MYPOINT;
extern "C" PINVOKELIB_API int TestArrayOfStructs( MYPOINT* pPointArray, int size );
//*************************************************************************************
typedef struct _MYPERSON
{
char* first;
char* last;
} MYPERSON;
extern "C" PINVOKELIB_API int TestArrayOfStructs2( MYPERSON* pPersonArray, int size );
//*************************************************************************************
typedef struct _MYPERSON2
{
MYPERSON* person;
int age;
} MYPERSON2;
extern "C" PINVOKELIB_API int TestStructInStruct( MYPERSON2* pPerson2 );
//*************************************************************************************
typedef struct _MYPERSON3
{
MYPERSON person;
int age;
} MYPERSON3;
extern "C" PINVOKELIB_API void TestStructInStruct3( MYPERSON3 person3 );
//*************************************************************************************
union MYUNION
{
int i;
double d;
};
extern "C" PINVOKELIB_API void TestUnion( MYUNION u, int type );
union MYUNION2
{
int i;
char str[128];
};
extern "C" PINVOKELIB_API void TestUnion2( MYUNION2 u, int type );
//*************************************************************************************
typedef bool (CALLBACK *FPTR)( int i );
extern "C" PINVOKELIB_API void TestCallBack( FPTR pf, int value );
typedef bool (CALLBACK *FPTR2)( char* str );
extern "C" PINVOKELIB_API void TestCallBack2( FPTR2 pf2, char* value );
//*************************************************************************************
typedef struct _MYSTRSTRUCT
{
wchar_t* buffer;
UINT size;
} MYSTRSTRUCT;
// buffer is an in/out param
extern "C" PINVOKELIB_API void TestStringInStruct( MYSTRSTRUCT* pStruct );
typedef struct _MYSTRSTRUCT2
{
char* buffer;
UINT size;
} MYSTRSTRUCT2;
// buffer is in/out param
extern "C" PINVOKELIB_API void TestStringInStructAnsi( MYSTRSTRUCT2* pStruct );
extern "C" PINVOKELIB_API void TestOutArrayOfStructs( int* pSize, MYSTRSTRUCT2** ppStruct );
//*************************************************************************************
extern "C" PINVOKELIB_API char* TestStringAsResult();
//*************************************************************************************
enum DataType
{
DT_I2 = 1,
DT_I4,
DT_R4,
DT_R8,
DT_STR
};
extern "C" PINVOKELIB_API void SetData( DataType typ, void* object );
//*************************************************************************************
typedef struct _MYARRAYSTRUCT
{
bool flag;
int vals[ 3 ];
} MYARRAYSTRUCT;
extern "C" PINVOKELIB_API void TestArrayInStruct( MYARRAYSTRUCT* pStruct );
//*************************************************************************************