Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

NativeCallable Attribute could not be found #6187

Closed
rickge opened this issue Aug 7, 2018 · 11 comments
Closed

NativeCallable Attribute could not be found #6187

rickge opened this issue Aug 7, 2018 · 11 comments

Comments

@rickge
Copy link

rickge commented Aug 7, 2018

I've created the HelloWorld example and successfully published using the ILCompiler alpha version '1.0.0-alpha-26807-01', and created a win-x64 exe. I wanted to add a new class with a native callable method exposed and attempted to add the following test class into my HelloWorld namespace:

public class TestCallMe
{
	TestCallMe()
	{
	}

	[NativeCallable]
	public static void CallMe(int a, int b)
	{
		Console.WriteLine(string.Format("{0} plus {1} yields {2}.", a, b, a + b));
	}
}

However, I am not able to find where the NativeCallable attribute is defined. My project is a .Net Core 2.1 version and I've opened it with Visual Studio 15.7.6.

The error I get indicates the attribute isn't found.
Program.cs(21,4): error CS0246: The type or namespace name 'NativeCallableAttribute' could not be found (are you missing a using directive or an assembly reference?) [C:\Users\208005772\Documents\Visual Studio 2017\Projects\SampleCoreRT\SampleCoreRT\SampleCoreRT.csproj]
Program.cs(21,4): error CS0246: The type or namespace name 'NativeCallable' could not be found (are you missing a using directive or an assembly reference?) [C:\Users\208005772\Documents\Visual Studio 2017\Projects\SampleCoreRT\SampleCoreRT\SampleCoreRT.csproj]

@MichalStrehovsky
Copy link
Member

You have to define your own, like this:

namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Method)]
public sealed class NativeCallableAttribute : Attribute
{
public string EntryPoint;
public CallingConvention CallingConvention;
public NativeCallableAttribute() { }
}
}

The attribute is not officially exposed from any SDK. The compiler will match it by namespace and name (it doesn't have to be defined in a special assembly).

@rickge
Copy link
Author

rickge commented Aug 7, 2018

Thanks for your answer. Creating that attribute in my assembly corrected the compiler error. When I publish (dotnet publish -r win-x64 -c debug), I get the compiled HelloWorld exe file. When I view this exe file using dependency walker, I don't see the callable method that I added.
I also tried creating a full .Net Framework console project and adding the following:

	static void Main(string[] args)
	{
		CallMe(4, 5);
	}

	[DllImport("HelloWorld.exe", CallingConvention = CallingConvention.StdCall)]
	public static extern void CallMe(int a, int b);

The .Net Framework CPU architecture is set to x64 and the call of "CallMe" does load the assembly, but I get an exception "Unable to find an entry point named 'CallMe' in DLL 'HelloWorld.exe'

Is there anything else you can think of that I might be missing to get the entry point exported?
Thanks.

@MichalStrehovsky
Copy link
Member

You need to build a library (DLL file), not an EXE. We don't generate the named exports for EXEs (we technically could, but the compiler doesn't do it). Will DLL work for you or do you need EXE?

The instructions to make this work with a DLL are here: #5703.

@mattwarren
Copy link
Contributor

@rickge BTW if you want another way to see all the methods inside the compiled .exe, you can use the DUMPBIN tool and the /DISASM cmd-line switch.

I used this whilst writing a post on CoreRT and it gives loads of useful info.

@rickge
Copy link
Author

rickge commented Aug 7, 2018

Thanks. Actually I wanted a dll, but couldn't figure out how to build it. I created a new .Net Core 2.1 class library and added my NativeCallable attributed method to it and used the command at the above post (or a link from the down in the post where the command is documented: #5154)
dotnet build /t:LinkNative /p:NativeLib=Shared
Currently getting an error for that build command but I'll see if I can figure that out.... probably something caused by my having just donated blood to the Red Cross. Do I need to create a LinkNative target for the project?

PS C:\Proj.DotNet\SampleCoreRT\CoreLibNative> dotnet build /t:LinkNative /p:NativeLib=Shared
Microsoft (R) Build Engine version 15.7.179.6572 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

Restore completed in 49.43 ms for C:\Proj.DotNet\SampleCoreRT\CoreLibNative\CoreLibNative.csproj.
CoreLibNative -> C:\Proj.DotNet\SampleCoreRT\CoreLibNative\bin\Debug\netcoreapp2.1\CoreLibNative.dll
C:\Proj.DotNet\SampleCoreRT\CoreLibNative\CoreLibNative.csproj : error MSB4057: The target "LinkNative" does not exist in the project.

Build FAILED.

C:\Proj.DotNet\SampleCoreRT\CoreLibNative\CoreLibNative.csproj : error MSB4057: The target "LinkNative" does not exist in the project.
0 Warning(s)
1 Error(s)

@MichalStrehovsky
Copy link
Member

I think you need to do dotnet publish, not dotnet build. The instructions in the open pull request to add docs are the most up to date: https://github.com/dotnet/corert/pull/5703/files

@rickge
Copy link
Author

rickge commented Aug 7, 2018

I'm getting closer and am sorry to be such a bother.

The publish creates a .lib, which I didn't expect for a win-x64 target, but I get an error when it is looking for a debug symbols file.

PS C:\Proj.DotNet\SampleCoreRT\CoreLibNative> dotnet publish /p:NativeLib=Static -r win-x64
Microsoft (R) Build Engine version 15.7.179.6572 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

Restore completed in 70.92 ms for C:\Proj.DotNet\SampleCoreRT\CoreLibNative\CoreLibNative.csproj.
CoreLibNative -> C:\Proj.DotNet\SampleCoreRT\CoreLibNative\bin\Debug\netcoreapp2.1\win-x64\CoreLibNative.dll
Generating native code
Microsoft (R) Library Manager Version 14.14.26433.0
Copyright (C) Microsoft Corporation. All rights reserved.

"/OUT:bin\Debug\netcoreapp2.1\win-x64\native\CoreLibNative.lib"
"obj\Debug\netcoreapp2.1\win-x64\native\CoreLibNative.obj"
CoreLibNative -> C:\Proj.DotNet\SampleCoreRT\CoreLibNative\bin\Debug\netcoreapp2.1\win-x64\publish
C:\Users\208005772.nuget\packages\microsoft.dotnet.ilcompiler\1.0.0-alpha-26807-02\build\Microsoft.NETCore.Native.Publish.targets(76,5): error MSB3030: Could not copy the file "bin\Debug\netcoreapp2.1\win-x64\native\CoreLibNative.pdb" because it was not found. [C:\Proj.DotNet\SampleCoreRT\CoreLibNative\CoreLibNative.csproj]

@jkotas
Copy link
Member

jkotas commented Aug 7, 2018

Could not copy the file "bin\Debug\netcoreapp2.1\win-x64\native\CoreLibNative.pdb" because it was not found.

This looks like a regression introduced by #5588. You should be able to ignore this error for now.

@MichalStrehovsky
Copy link
Member

The publish creates a .lib, which I didn't expect for a win-x64 target

If you want a DLL, you need to specify /p:NativeLib=Shared, not /p:NativeLib=Static.

@rickge
Copy link
Author

rickge commented Aug 8, 2018

My bad on the static vs shared. When I use Shared, I get an error finding a library .def file. I'm guessing I need to do a build step to create the .def file per #5154 or create the .def on my own?

PS C:\Proj.DotNet\SampleCoreRT\CoreLibNative> dotnet publish /p:NativeLib=Shared -r win-x64
Microsoft (R) Build Engine version 15.7.179.6572 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 57.67 ms for C:\Proj.DotNet\SampleCoreRT\CoreLibNative\CoreLibNative.csproj.
  CoreLibNative -> C:\Proj.DotNet\SampleCoreRT\CoreLibNative\bin\Debug\netcoreapp2.1\win-x64\CoreLibNative.dll
LINK : fatal error LNK1104: cannot open file 'obj\Debug\netcoreapp2.1\win-x64\native\CoreLibNative.def' [C:\Proj.DotNet\SampleCoreRT\CoreLibNative\CoreLibNative.csproj]
C:\Users\208005772\.nuget\packages\microsoft.dotnet.ilcompiler\1.0.0-alpha-26807-02\build\Microsoft.NETCore.Native.targets(236,5): error MSB3073: The command ""C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.14.26428\bin\Hostx64\x64\link.exe"  @"obj\Debug\netcoreapp2.1\win-x64\native\link.rsp"" exited with code 1104. [C:\Proj.DotNet\SampleCoreRT\CoreLibNative\CoreLibNative.csproj]```

@rickge
Copy link
Author

rickge commented Aug 8, 2018

I left off the configuration option. Using:

dotnet publish /p:NativeLib=Shared -r win-x64 -c debug

created the desired dll with the desired entry point.
Thanks for all of your help.

@rickge rickge closed this as completed Aug 9, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants