Call a C function that has parameter of float got NotSupportedException?

T

Tony Liu

Dear All:

I create a very simple DLL by using EVC to test the problem. (The platform I
am working for those program is WinCE.NET)

*******************************************************
The header looks like:

#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif

TESTDLL_API LONG fnTestF(FLOAT var1);

*******************************************************
The C source looks like:
#include "stdafx.h"
#include "TestDll.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;
}


TESTDLL_API LONG fnTestF(FLOAT var1)
{
return 0;
}

*******************************************************
The DEF file look like:
LIBRARY TestDll
EXPORTS
fnTestF
*******************************************************

After build up this DLL, I try to write a C# program to call this function.
The C# program looks like:

[DllImport("testdll.dll")]
private static extern Int32 fnTestF
(
Single fPeriod
);

When I call this function likes bellow:
Single fVal = 0.1f;
Int32 i32Ret;

try
{
i32Ret = fnTestF(fVal);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Exception!");
}

I always get an exception called "NotSupportedException".

Any idea about this?

Thanks!

Tony Liu
 
G

Gary James

Tony, if you're code is in a .CPP file, you may be generating a mangled name
function. Open your DLL in in the "Depends" utility and look in the
exports section to see what the name look likes. If it is mangled, just add
the following to your .H file.

#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif

// ---- new code ----
#ifdef __cplusplus
extern "C"{
#endif
// ----------------------

TESTDLL_API LONG fnTestF(FLOAT var1);

// ---- new code ----
#ifdef __cplusplus
};
#endif
// ----------------------


Gary ...
 
T

Tony Liu

Finally, I found a document in MSDN 2003:
The topic of the document is "Non Blittable Types and Marshaling Support"
A section of this document:
Visual C and Visual C++ Marshaling Results
The following table lists Visual C and Visual C++ types used by the
marshaler for managed types, with Windows CE .NET as the operating system
hosting the unmanaged code. This list is not comprehensive.

Managed Code
Visual C# Types
Managed Code
Visual Basic Types
Unmanaged Code
ByVal
Unmanaged Code
ByRef

bool
Boolean
BYTE
BYTE *

int
Integer
INT32
INT32 *

short
Short
SHORT
SHORT *

long
Long
Not supported
INT64 *

char
Char
WCHAR
WCHAR *

float
Single
Not supported
FLOAT *

double
Double
Not supported
DOUBLE *

String
String
WCHAR *
Not supported

StringBuilder
StringBuilder
WCHAR *
Not supported

DateTime
DateTime
Not supported
Not supported

int[]
Integer()
INT32 *, INT32[]
Not supported



I think that is the reason why I cannot pass a "FLOAT" by value.

Tony



Gary James said:
Tony, if you're code is in a .CPP file, you may be generating a mangled name
function. Open your DLL in in the "Depends" utility and look in the
exports section to see what the name look likes. If it is mangled, just add
the following to your .H file.

#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif

// ---- new code ----
#ifdef __cplusplus
extern "C"{
#endif
// ----------------------

TESTDLL_API LONG fnTestF(FLOAT var1);

// ---- new code ----
#ifdef __cplusplus
};
#endif
// ----------------------


Gary ...


Tony Liu said:
Dear All:

I create a very simple DLL by using EVC to test the problem. (The
platform
I
am working for those program is WinCE.NET)

*******************************************************
The header looks like:

#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif

TESTDLL_API LONG fnTestF(FLOAT var1);

*******************************************************
The C source looks like:
#include "stdafx.h"
#include "TestDll.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;
}


TESTDLL_API LONG fnTestF(FLOAT var1)
{
return 0;
}

*******************************************************
The DEF file look like:
LIBRARY TestDll
EXPORTS
fnTestF
*******************************************************

After build up this DLL, I try to write a C# program to call this function.
The C# program looks like:

[DllImport("testdll.dll")]
private static extern Int32 fnTestF
(
Single fPeriod
);

When I call this function likes bellow:
Single fVal = 0.1f;
Int32 i32Ret;

try
{
i32Ret = fnTestF(fVal);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Exception!");
}

I always get an exception called "NotSupportedException".

Any idea about this?

Thanks!

Tony Liu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top