Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

External Exception E0434352 using netcore #130

Closed
phillsonntag opened this issue Dec 16, 2019 · 7 comments
Closed

External Exception E0434352 using netcore #130

phillsonntag opened this issue Dec 16, 2019 · 7 comments

Comments

@phillsonntag
Copy link

Hello,

I'm currently struggling with the implementation of an exported .NET Core function in my Delphi application. Just before I submitted this issue I also tried to implement the same dll with the same function in C++.
Both implementations threw the same error 0xE0434352.
When I inspect the dll using a dependency inspector, the right dependencies are set and the function is correctly exported.

  • v1.7beta3:
  • Manager: Tried both x86, x64 and Direct-Mod/Cecil in all possible variants.
  • Project type: .NET Core 3.1.100 Class Library
  • Environment: Visual Studio 2019 v16.4.1, Windows SDK 10.0.17763.0

Used configuration:

  • 64 bit (bot Delphi and .NET Core)

Source

ExportsDemo.dll -> Exports.cs:

using System.Windows.Forms;

namespace ExportsDemo
{
    public static class Exports
    {
        [DllExport]
        public static void DemoProc()
        {
            MessageBox.Show("Hello world!");
        }
    }
}

ExportsDemo -> ExportsDemo.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>
  <PropertyGroup>
    <DllExportIdent>19A9E616-EECD-4703-897E-4BD8A257C0F0</DllExportIdent>
    <DllExportMetaLibName>DllExport.dll</DllExportMetaLibName>
    <DllExportNamespace>ExportsDemo</DllExportNamespace>
    <DllExportDDNSCecil>true</DllExportDDNSCecil>
    <PlatformTarget>x64</PlatformTarget>
    <DllExportOrdinalsBase>1</DllExportOrdinalsBase>
    <DllExportGenExpLib>false</DllExportGenExpLib>
    <DllExportOurILAsm>false</DllExportOurILAsm>
    <DllExportSysObjRebase>false</DllExportSysObjRebase>
    <DllExportLeaveIntermediateFiles>false</DllExportLeaveIntermediateFiles>
    <DllExportTimeout>30000</DllExportTimeout>
    <DllExportPeCheck>2</DllExportPeCheck>
    <DllExportPatches>0</DllExportPatches>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="DllExport, PublicKeyToken=8337224c9ad9e356">
      <HintPath>$(SolutionDir)packages\DllExport.1.7.0-beta3\gcache\$(DllExportMetaXBase)\$(DllExportNamespace)\$(DllExportMetaLibName)</HintPath>
      <Private>False</Private>
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="System.Windows.Forms">
      <HintPath>..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Windows.Forms.dll</HintPath>
    </Reference>
  </ItemGroup>
  <ImportGroup Label=".NET DllExport">
    <Import Project="$(SolutionDir)packages\DllExport.1.7.0-beta3\tools\net.r_eg.DllExport.targets" Condition="Exists($([MSBuild]::Escape('$(SolutionDir)packages\DllExport.1.7.0-beta3\tools\net.r_eg.DllExport.targets')))" Label="8337224c9ad9e356" />
  </ImportGroup>
  <Target Name="DllExportRestorePkg" BeforeTargets="PrepareForBuild">
    <Error Condition="!Exists('$(SolutionDir)DllExport.bat')" Text="DllExport.bat is not found. Path: '$(SolutionDir)' - https://github.com/3F/DllExport" />
    <Exec Condition="('$(DllExportModImported)' != 'true' Or !Exists('$(SolutionDir)packages\DllExport.1.7.0-beta3\tools\net.r_eg.DllExport.targets')) And Exists('$(SolutionDir)DllExport.bat')" Command="DllExport.bat  -action Restore" WorkingDirectory="$(SolutionDir)" />
  </Target>
  <Target Name="DllExportRPkgDynamicImport" BeforeTargets="PostBuildEvent" DependsOnTargets="GetFrameworkPaths" Condition="'$(DllExportModImported)' != 'true' And '$(DllExportRPkgDyn)' != 'false'">
    <MSBuild BuildInParallel="true" UseResultsCache="true" Projects="$(MSBuildProjectFullPath)" Properties="DllExportRPkgDyn=true" Targets="Build" />
  </Target>
</Project>

C++ Project (PlusPlusDemo):

#include <iostream>
#include <windows.h>

typedef int(__stdcall *f_funci)();

int main()
{
	HINSTANCE hGetProcIDDLL = LoadLibraryA("C:\\Users\\psn\\Desktop\\ExportsDemo.dll");

	if (!hGetProcIDDLL) {
		std::cout << "could not load the dynamic library" << std::endl;
		return EXIT_FAILURE;
	}

	// resolve function address here
	f_funci funci = (f_funci)GetProcAddress(hGetProcIDDLL, "DemoProc");
	if (!funci) {
		std::cout << "could not locate the function" << std::endl;
		return EXIT_FAILURE;
	}

	funci();
	return EXIT_SUCCESS;
}

(I don't really know the syntax of C++, just wanted to make sure the exception doesn't belong to Delphi.)


Logs

C++ Exception:
Unhandled exception at 0x00007FFB9336A839 (KernelBase.dll) in PlusPlusDemo.exe: 0xE0434352 (parameters: 0xFFFFFFFF80070002, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x00007FFB85F00000).

C++ CallStack:

KernelBase.dll!00007ffb9336a839()
clr.dll!00007ffb85f1a3f1()
clr.dll!00007ffb860ee7d9()
clr.dll!00007ffb86338585()
mscoreei.dll!00007ffb869fb26a()
mscoreei.dll!00007ffb86a099c2()
mscoreei.dll!00007ffb869e644e()
PlusPlusDemo.exe!main() Line 27
PlusPlusDemo.exe!invoke_main() Line 79
PlusPlusDemo.exe!__scrt_common_main_seh() Line 288
PlusPlusDemo.exe!__scrt_common_main() Line 331
PlusPlusDemo.exe!mainCRTStartup() Line 17
kernel32.dll!00007ffb940c7bd4()
ntdll.dll!00007ffb9562ced1()

Output of Delphi using the Visual Studio Debugger:
VS2019_Delphi.log

Thank you in advance for the time and effort you put in this project.

@3F
Copy link
Owner

3F commented Dec 16, 2019

@phillsonntag, Did you try with rebasing system object? Rebase System Object option.

See also related #125.

@3F
Copy link
Owner

3F commented Dec 16, 2019

Thank you in advance for the time and effort you put in this project.

Yes, recent 2 years have been very difficult for me :( And it was very difficult to combine all that with opensource activities. Really hard for my time and generally for me personally.

But I really like that all this are still helpful, and I still can continue develop something like this. Who follows me also knows that I had plan (and still have, see related #90) for native implementation. But today we're still using this through ilasm and through my custom assembler features for .NET Core support, as you can see. Well, time will tell. I'm still alive and this is good point to continue develop something in OSS and at all :)

I want to thanks again to all who supported me! Thank you, guys!

This project personally aggregated a bit of sum (especially when comparing with stars on github with my other projects). For all this years it was just about $80 for DllExport :) Soon I will try count this in details and personally donate to Robert and Cecil project something from that amount.

@3F
Copy link
Owner

3F commented Dec 17, 2019

@phillsonntag,

I've just checked your examples. Thanks for the detailed report information! I really appreciate it because it really helps to save a bit of time in attempts to reproduce problem.

So, I don't see the problems when rebasing system object. Thus, please consider use the related option. Details in #125 as I mentioned above.

Let me know if you have other problems. Thanks!

@3F 3F added duplicate and removed bug labels Dec 17, 2019
@3F 3F closed this as completed Dec 17, 2019
@3F
Copy link
Owner

3F commented Dec 17, 2019

ah yes:

typedef int(__stdcall *f_funci)();

FYI: We're using __cdecl by default for any exports! For __stdcall you need to configure DllExport attribute.

@3F 3F added the bug label Dec 17, 2019
@3F 3F added this to the 1.7 milestone Dec 17, 2019
@phillsonntag
Copy link
Author

phillsonntag commented Dec 18, 2019

Finally! It works, thank you very much for your help. The rebase did it. I missed something, but it finally works now. THANKS! :D

EDIT: I also tried to define the stdcall before, but it didn't work either, so I tried everything I could find :D

@phillsonntag
Copy link
Author

FYI: When I explicitly define Cdecl in the DllExport attribute, and import it in C++ via StdCall it also works. I don't know if this is wanted behaviour.

@3F
Copy link
Owner

3F commented Dec 18, 2019

Finally! It works, thank you very much for your help. The rebase did it.

Good!

Cdecl in the DllExport attribute, and import it in C++ via StdCall it also works.

For your case above it does not matter:

C++ funci() -> ... -> CLR MessageBox -> (__stdcall) -> user32

Calling convention just declares the rules for how to use stack, registers, arguments between calling; Mainly, who cleans the stack and how arguments are passed. Please read MSDN for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants