From b0f9d291e388befc22788e6f96b4b6fb9b6cc84a Mon Sep 17 00:00:00 2001 From: albert-du <52804499+albert-du@users.noreply.github.com> Date: Sat, 5 Feb 2022 20:06:11 -0800 Subject: [PATCH] EntryPointNotFoundException F# snippets --- .../Overview/badcall1.fs | 24 +++++++++++++++++++ .../Overview/fiximportassembly1.fs | 7 ++++++ .../Overview/fs.fsproj | 16 +++++++++++++ .../Overview/importassembly1.fs | 16 +++++++++++++ .../Overview/mangle1.fs | 16 +++++++++++++ .../Overview/mangle2.fs | 13 ++++++++++ .../Overview/nofunction1.fs | 19 +++++++++++++++ .../Overview/stringutilities.fs | 6 +++++ xml/System/EntryPointNotFoundException.xml | 7 ++++++ 9 files changed, 124 insertions(+) create mode 100644 snippets/fsharp/System/EntryPointNotFoundException/Overview/badcall1.fs create mode 100644 snippets/fsharp/System/EntryPointNotFoundException/Overview/fiximportassembly1.fs create mode 100644 snippets/fsharp/System/EntryPointNotFoundException/Overview/fs.fsproj create mode 100644 snippets/fsharp/System/EntryPointNotFoundException/Overview/importassembly1.fs create mode 100644 snippets/fsharp/System/EntryPointNotFoundException/Overview/mangle1.fs create mode 100644 snippets/fsharp/System/EntryPointNotFoundException/Overview/mangle2.fs create mode 100644 snippets/fsharp/System/EntryPointNotFoundException/Overview/nofunction1.fs create mode 100644 snippets/fsharp/System/EntryPointNotFoundException/Overview/stringutilities.fs diff --git a/snippets/fsharp/System/EntryPointNotFoundException/Overview/badcall1.fs b/snippets/fsharp/System/EntryPointNotFoundException/Overview/badcall1.fs new file mode 100644 index 00000000000..37de1887b16 --- /dev/null +++ b/snippets/fsharp/System/EntryPointNotFoundException/Overview/badcall1.fs @@ -0,0 +1,24 @@ +module badcall1 + +// +open System +open System.Runtime.InteropServices + +[] +extern int MessageBox(IntPtr hwnd, String text, String caption, uint ``type``) + +[] +extern int MessageBoxW(IntPtr hwnd, String text, String caption, uint ``type``) + +try + MessageBox(IntPtr 0, "Calling the MessageBox Function", "Example", 0u) + |> ignore +with :? EntryPointNotFoundException as e -> + printfn $"{e.GetType().Name}:\n {e.Message}" + +try + MessageBoxW(IntPtr 0, "Calling the MessageBox Function", "Example", 0u) + |> ignore +with :? EntryPointNotFoundException as e -> + printfn $"{e.GetType().Name}:\n {e.Message}" +// \ No newline at end of file diff --git a/snippets/fsharp/System/EntryPointNotFoundException/Overview/fiximportassembly1.fs b/snippets/fsharp/System/EntryPointNotFoundException/Overview/fiximportassembly1.fs new file mode 100644 index 00000000000..078527d1316 --- /dev/null +++ b/snippets/fsharp/System/EntryPointNotFoundException/Overview/fiximportassembly1.fs @@ -0,0 +1,7 @@ +module fiximportassembly1 + +// +printfn $"""{StringUtilities.SayGoodMorning "Dakota"}""" +// The example displays the following output: +// A top of the morning to you, Dakota! +// \ No newline at end of file diff --git a/snippets/fsharp/System/EntryPointNotFoundException/Overview/fs.fsproj b/snippets/fsharp/System/EntryPointNotFoundException/Overview/fs.fsproj new file mode 100644 index 00000000000..3f484de2e56 --- /dev/null +++ b/snippets/fsharp/System/EntryPointNotFoundException/Overview/fs.fsproj @@ -0,0 +1,16 @@ + + + Exe + net6.0 + + + + + + + + + + + + \ No newline at end of file diff --git a/snippets/fsharp/System/EntryPointNotFoundException/Overview/importassembly1.fs b/snippets/fsharp/System/EntryPointNotFoundException/Overview/importassembly1.fs new file mode 100644 index 00000000000..317ffa90735 --- /dev/null +++ b/snippets/fsharp/System/EntryPointNotFoundException/Overview/importassembly1.fs @@ -0,0 +1,16 @@ +module importassembly1 + +// +open System +open System.Runtime.InteropServices + +[] +extern String SayGoodMorning(String name) + +printfn $"""{SayGoodMorning "Dakota"}""" +// The example displays the following output: +// Unhandled Exception: System.EntryPointNotFoundException: Unable to find an entry point +// named 'GoodMorning' in DLL 'StringUtilities.dll'. +// at Example.GoodMorning(String& name) +// at Example.Main() +// \ No newline at end of file diff --git a/snippets/fsharp/System/EntryPointNotFoundException/Overview/mangle1.fs b/snippets/fsharp/System/EntryPointNotFoundException/Overview/mangle1.fs new file mode 100644 index 00000000000..03c5c89f95f --- /dev/null +++ b/snippets/fsharp/System/EntryPointNotFoundException/Overview/mangle1.fs @@ -0,0 +1,16 @@ +module mangle1 + +// +open System +open System.Runtime.InteropServices + +[] +extern int Double(int number) + +printfn $"{Double 10}" +// The example displays the following output: +// Unhandled Exception: System.EntryPointNotFoundException: Unable to find +// an entry point named 'Double' in DLL '.\TestDll.dll'. +// at Example.Double(Int32 number) +// at Example.Main() +// \ No newline at end of file diff --git a/snippets/fsharp/System/EntryPointNotFoundException/Overview/mangle2.fs b/snippets/fsharp/System/EntryPointNotFoundException/Overview/mangle2.fs new file mode 100644 index 00000000000..bf784361ccc --- /dev/null +++ b/snippets/fsharp/System/EntryPointNotFoundException/Overview/mangle2.fs @@ -0,0 +1,13 @@ +module mangle2 + +// +open System +open System.Runtime.InteropServices + +[] +extern int Double(int number) + +printfn $"{Double 10}" +// The example displays the following output: +// 20 +// \ No newline at end of file diff --git a/snippets/fsharp/System/EntryPointNotFoundException/Overview/nofunction1.fs b/snippets/fsharp/System/EntryPointNotFoundException/Overview/nofunction1.fs new file mode 100644 index 00000000000..ce17779a344 --- /dev/null +++ b/snippets/fsharp/System/EntryPointNotFoundException/Overview/nofunction1.fs @@ -0,0 +1,19 @@ +module nofunction1 + +// +open System +open System.Runtime.InteropServices + +[] +extern int GetMyNumber() + +try + let number = GetMyNumber() + () +with :? EntryPointNotFoundException as e -> + printfn $"{e.GetType().Name}:\n {e.Message}" + +// The example displays the following output: +// EntryPointNotFoundException: +// Unable to find an entry point named 'GetMyNumber' in DLL 'User32.dll'. +// \ No newline at end of file diff --git a/snippets/fsharp/System/EntryPointNotFoundException/Overview/stringutilities.fs b/snippets/fsharp/System/EntryPointNotFoundException/Overview/stringutilities.fs new file mode 100644 index 00000000000..9310081a4ee --- /dev/null +++ b/snippets/fsharp/System/EntryPointNotFoundException/Overview/stringutilities.fs @@ -0,0 +1,6 @@ +// +module StringUtilities + +let SayGoodMorning name = + $"A top of the morning to you, %s{name}!" +// \ No newline at end of file diff --git a/xml/System/EntryPointNotFoundException.xml b/xml/System/EntryPointNotFoundException.xml index 06882b87cfc..00a5afdf0f2 100644 --- a/xml/System/EntryPointNotFoundException.xml +++ b/xml/System/EntryPointNotFoundException.xml @@ -57,11 +57,13 @@ - The call to a function in a Windows DLL cannot be resolved because the function cannot be found. In the following example, an exception is thrown because User32.dll does not include a function named `GetMyNumber`. :::code language="csharp" source="~/snippets/csharp/System/EntryPointNotFoundException/Overview/nofunction1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/snippets/fsharp/System/EntryPointNotFoundException/Overview/nofunction1.fs" id="Snippet1"::: :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.entrypointnotfoundexception.class/vb/nofunction1.vb" id="Snippet1"::: - The call to a function in a Windows DLL cannot be resolved because the name used in the method call does not match a name found in the assembly. Frequently, this occurs because the field is either implicitly or explicitly set to `true`, the called method includes one or more string parameters and has both an ANSI and a Unicode version, and the name used in the method call does not correspond to the name of this ANSI or Unicode version. The following example provides an illustration by attempting to call the Windows `MessageBox` function in User32.dll. Because the first method definition specifies for string marshaling, the common language looks for the wide-character version of the function, `MessageBoxW`, instead of the name used in the method call, `MessageBox`. The second method definition corrects this problem by calling the `MessageBoxW` instead of the `MessageBox` function. :::code language="csharp" source="~/snippets/csharp/System/EntryPointNotFoundException/Overview/badcall1.cs" id="Snippet2"::: + :::code language="fsharp" source="~/snippets/fsharp/System/EntryPointNotFoundException/Overview/badcall1.fs" id="Snippet2"::: :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.entrypointnotfoundexception.class/vb/badcall1.vb" id="Snippet2"::: - You are trying to call a function in a dynamic link library by its simple name rather than its decorated name. Typically, the C++ compiler generates a decorated name for DLL functions. For example, the following C++ code defines a function named `Double` in a library named TestDll.dll. @@ -71,11 +73,13 @@ When the code in the following example tries to call the function, an exception is thrown because the `Double` function cannot be found. :::code language="csharp" source="~/snippets/csharp/System/EntryPointNotFoundException/Overview/mangle1.cs" id="Snippet7"::: + :::code language="fsharp" source="~/snippets/fsharp/System/EntryPointNotFoundException/Overview/mangle1.fs" id="Snippet7"::: :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.entrypointnotfoundexception.class/vb/mangle1.vb" id="Snippet7"::: However, if the function is called by using its decorated name (in this case, `?Double@@YAHH@Z`), the function call succeeds, as the following example shows. :::code language="csharp" source="~/snippets/csharp/System/EntryPointNotFoundException/Overview/mangle2.cs" id="Snippet8"::: + :::code language="fsharp" source="~/snippets/fsharp/System/EntryPointNotFoundException/Overview/mangle2.fs" id="Snippet8"::: :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.entrypointnotfoundexception.class/vb/mangle2.vb" id="Snippet8"::: You can find the decorated names of functions exported by a DLL by using a utility such as Dumpbin.exe. @@ -83,16 +87,19 @@ - You are attempting to call a method in a managed assembly as if it were an unmanaged dynamic link library. To see this in action, compile the following example to an assembly named StringUtilities.dll. :::code language="csharp" source="~/snippets/csharp/System/EntryPointNotFoundException/Overview/stringutilities.cs" id="Snippet3"::: + :::code language="fsharp" source="~/snippets/fsharp/System/EntryPointNotFoundException/Overview/stringutilities.fs" id="Snippet3"::: :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.entrypointnotfoundexception.class/vb/stringutilities.vb" id="Snippet3"::: Then compile and execute the following example, which attempts to call the `StringUtilities.SayGoodMorning` method in the StringUtilities.dll dynamic link library as if it were unmanaged code. The result is an exception. :::code language="csharp" source="~/snippets/csharp/System/EntryPointNotFoundException/Overview/importassembly1.cs" id="Snippet4"::: + :::code language="fsharp" source="~/snippets/fsharp/System/EntryPointNotFoundException/Overview/importassembly1.fs" id="Snippet4"::: :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.entrypointnotfoundexception.class/vb/importassembly1.vb" id="Snippet4"::: To eliminate the exception, add a reference to the managed assembly and access the `StringUtilities.SayGoodMorning` method just as you would access any other method in managed code, as the following example does. :::code language="csharp" source="~/snippets/csharp/System/EntryPointNotFoundException/Overview/fiximportassembly1.cs" id="Snippet5"::: + :::code language="fsharp" source="~/snippets/fsharp/System/EntryPointNotFoundException/Overview/fiximportassembly1.fs" id="Snippet5"::: :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.entrypointnotfoundexception.class/vb/fiximportassembly1.vb" id="Snippet5"::: - You are trying to call a method in a COM DLL as if it were a Windows DLL. To access a COM DLL, select the **Add Reference** option in Visual Studio to add a reference to the project, and then select the type library from the **COM** tab.