Files
yallie 9fa3874800 Added the contents of the archive.
Moved the original file to the archive subfolder.
2017-11-20 16:11:42 +03:00

211 lines
4.7 KiB
C++

// ==++==
//
//
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
//
// The use and distribution terms for this software are contained in the file
// named license.txt, which can be found in the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by the
// terms of this license.
//
// You must not remove this notice, or any other, from this software.
//
//
// ==--==
// ===========================================================================
// File: nativedll.cpp
//
// native dll for FFI testing, can be reused for other tests too
// ===========================================================================
#include "windows.h"
#include "stdlib.h"
#include "cor.h"
#include "corffi.h"
extern "C" BOOL WINAPI DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID pvReserved )
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
if (PAL_Initialize(NULL, NULL) != 0)
return FALSE;
DisableThreadLibraryCalls(hInst);
break;
case DLL_PROCESS_DETACH:
PAL_Terminate();
break;
default:
break;
}
return TRUE;
}
void fail(char *msg)
{
fprintf(stderr, "Failed: %s\n", msg);
exit(1);
}
// simple delegate roundtrip
typedef int (__stdcall *MySimpleDelegate)(int x);
MySimpleDelegate g_CachedSimpleDelegate;
extern "C" void __stdcall CacheSimpleDelegate(MySimpleDelegate pfn)
{
g_CachedSimpleDelegate = pfn;
}
extern "C" int __stdcall CallSimpleDelegate(MySimpleDelegate pfn, int x)
{
if (pfn == NULL)
pfn = g_CachedSimpleDelegate;
return pfn(x) + 1;
}
// delegate roundtrip
typedef double (__stdcall *MyDelegate)(IUnknown* punk);
MyDelegate g_CachedDelegate;
extern "C" void __stdcall CacheDelegate(MyDelegate pfn)
{
g_CachedDelegate = pfn;
}
extern "C" double __stdcall CallDelegate(MyDelegate pfn, IUnknown* punk)
{
if (pfn == NULL)
pfn = g_CachedDelegate;
return pfn(punk) + 1;
}
// ffi roundtrip
extern "C" double __stdcall CallFFI(IUnknown* pcallback, IUnknown* punk)
{
IManagedInstanceWrapper* pmiw;
VARIANT arg;
VARIANT retval;
HRESULT hr;
V_VT(&arg) = VT_UNKNOWN;
V_UNKNOWN(&arg) = punk;
pcallback->QueryInterface(IID_IManagedInstanceWrapper, (void**)&pmiw);
hr = pmiw->InvokeByName(
L"MyCallback", CorFFIInvokeMethod, 1, &arg, &retval);
pmiw->Release();
if (FAILED(hr))
fail("MyCallback failed");
if (V_VT(&retval) != VT_R8)
fail("Expected R8");
return V_R8(&retval) + 1;
}
// array marshalling
extern "C" int __stdcall Sum(int count, int* a)
{
int sum = 0;
for (int i = 0; i < count; i++)
sum += a[i];
return sum;
}
// array marshalling ex
extern "C" int __stdcall ObjectSum(int count, IUnknown** a)
{
int sum = 0;
for (int i = 0; i < count; i++) {
VARIANT var;
HRESULT hr;
IManagedInstanceWrapper* pmiw;
a[i]->QueryInterface(IID_IManagedInstanceWrapper, (void**)&pmiw);
hr = pmiw->InvokeByName(
L"Value", CorFFIGetProperty, 0, NULL, &var);
pmiw->Release();
if (FAILED(hr))
fail("get_Value failed");
if (V_VT(&var) != VT_I4) {
fail("Expected VT_I4");
}
sum += V_I4(&var);
}
return sum;
}
// errorinfo roundtrip
extern "C" HRESULT __stdcall ReallyBadError(IUnknown *punk)
{
HRESULT hr;
IErrorInfo* err;
ICreateErrorInfo *cerr;
BSTR bstr;
WCHAR buf[10000];
IManagedInstanceWrapper* pmiw;
punk->QueryInterface(IID_IManagedInstanceWrapper, (void**)&pmiw);
hr = pmiw->InvokeByName(
L"BadError", CorFFIInvokeMethod, 0, NULL, NULL);
pmiw->Release();
if (GetErrorInfo(0, &err) != S_OK)
fail("No error info!");
err->GetDescription(&bstr);
// printf("Description: %S\n", bstr);
err->Release();
_snwprintf(buf, 10000, L"qwerty %s", bstr);
SysFreeString(bstr);
if (CreateErrorInfo(&cerr) != S_OK)
fail("Failed to create error info!");
cerr->SetDescription(buf);
cerr->QueryInterface(IID_IErrorInfo, (void**)&err);
cerr->Release();
SetErrorInfo(0, err);
err->Release();
return E_FAIL;
}
// exception roundtrip
extern "C" void __stdcall Exception12345678(MyDelegate pfn, IUnknown* punk)
{
BOOL fException = FALSE;
PAL_TRY {
pfn(punk);
}
PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
fException = TRUE;
}
PAL_ENDTRY
if (!fException) {
fail("No exception thrown from managed code!");
}
RaiseException(0x12345678, EXCEPTION_NONCONTINUABLE_EXCEPTION, 0, NULL);
}
extern "C" MySimpleDelegate DelegateMarshal(MySimpleDelegate d)
{
return d;
}