Browse Source

Fixed ArgumentException due to nullptr arguments in Marshaling native function pointers. (#794)

pull/796/head
realvictorprm 10 years ago committed by Dimitar Dobrev
parent
commit
4307fb3303
  1. 2
      src/Generator/Generators/CLI/CLIMarshal.cs
  2. 6
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  3. 3
      tests/Common/Common.Tests.cs
  4. 5
      tests/Common/Common.cpp
  5. 3
      tests/Common/Common.h

2
src/Generator/Generators/CLI/CLIMarshal.cs

@ -249,7 +249,7 @@ namespace CppSharp.Generators.CLI
FunctionType function; FunctionType function;
if (decl.Type.IsPointerTo(out function)) if (decl.Type.IsPointerTo(out function))
{ {
Context.Return.Write("safe_cast<{0}>(", typedef); Context.Return.Write($"{Context.ReturnVarName} == nullptr ? nullptr : safe_cast<{typedef}>(");
Context.Return.Write("System::Runtime::InteropServices::Marshal::"); Context.Return.Write("System::Runtime::InteropServices::Marshal::");
Context.Return.Write("GetDelegateForFunctionPointer("); Context.Return.Write("GetDelegateForFunctionPointer(");
Context.Return.Write("IntPtr({0}), {1}::typeid))",Context.ReturnVarName, Context.Return.Write("IntPtr({0}), {1}::typeid))",Context.ReturnVarName,

6
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -249,9 +249,9 @@ namespace CppSharp.Generators.CSharp
Context.SupportBefore.WriteLine("var {0} = {1};", ptrName, Context.SupportBefore.WriteLine("var {0} = {1};", ptrName,
Context.ReturnVarName); Context.ReturnVarName);
Context.Return.Write("({1})Marshal.GetDelegateForFunctionPointer({0}, typeof({1}))", var res = $"{ptrName} == IntPtr.Zero? null : ({typedef})Marshal.GetDelegateForFunctionPointer({ptrName}, typeof({typedef}))";
ptrName, typedef.ToString()); Context.Return.Write(res);
return true; return true;
} }

3
tests/Common/Common.Tests.cs

@ -317,6 +317,9 @@ public class CommonTests : GeneratorTestFixture
var cdecl = delegates.CDecl(i => i); var cdecl = delegates.CDecl(i => i);
Assert.AreEqual(1, cdecl); Assert.AreEqual(1, cdecl);
var emptydelegeate = delegates.MarshalNullDelegate;
Assert.AreEqual(emptydelegeate, null);
} }
[Test] [Test]

5
tests/Common/Common.cpp

@ -421,6 +421,11 @@ void TestDelegates::MarshalDelegateInAnotherUnit(DelegateInAnotherUnit del)
{ {
} }
DelegateNullCheck TestDelegates::MarshalNullDelegate()
{
return nullptr;
}
void DelegateNamespace::f2(void (*)()) void DelegateNamespace::f2(void (*)())
{ {
} }

3
tests/Common/Common.h

@ -324,6 +324,7 @@ DLL_API int operator==(const Foo2& a, const Foo2& b)
typedef int (*DelegateInGlobalNamespace)(int); typedef int (*DelegateInGlobalNamespace)(int);
typedef int (STDCALL *DelegateStdCall)(int); typedef int (STDCALL *DelegateStdCall)(int);
typedef int (CDECL *DelegateCDecl)(int n); typedef int (CDECL *DelegateCDecl)(int n);
typedef void(*DelegateNullCheck)(void);
struct DLL_API TestDelegates struct DLL_API TestDelegates
{ {
@ -345,6 +346,8 @@ struct DLL_API TestDelegates
void MarshalDelegateInAnotherUnit(DelegateInAnotherUnit del); void MarshalDelegateInAnotherUnit(DelegateInAnotherUnit del);
DelegateNullCheck MarshalNullDelegate();
DelegateInClass A; DelegateInClass A;
DelegateInGlobalNamespace B; DelegateInGlobalNamespace B;
// As long as we can't marshal them make sure they're ignored // As long as we can't marshal them make sure they're ignored

Loading…
Cancel
Save