Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 778121
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 14, 20262026-05-14T19:42:51+00:00 2026-05-14T19:42:51+00:00

I want to use a Haskell function with the following type :: string ->

  • 0

I want to use a Haskell function with the following type ::
string -> string from a C# program.

I want to use hs-dotnet to bridge both worlds. The author claim that it’s possible, but provide no sample of this case. The only samples provided are the one to use .NET from Haskell.

Is there a sample of this use, or how to use it? (I used .NET Reflector on the bridging assembly, but I didn’t understand a thing.)

  • 1 1 Answer
  • 4 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-14T19:42:52+00:00Added an answer on May 14, 2026 at 7:42 pm

    While your way works, it’s worth noting that the dificulties you encountered were of your own doing unfortunately (and not a bug in GHC) 🙁 (The following assumes you used the GHC documentation when building the DLL and have your RTS loading in DLL main).

    For the first part, the memory allocation issues you present, there’s a much easier C# native way of handling this, which is unsafe code. Any memory allocated in unsafe code will be allocated outside the managed heap. So this would negate the need for C trickery.

    The second part is the use of the LoadLibrary in C#. The reason P/Invoke can’t find your export is quite simple: in your Haskell code you declared the export statement using ccall, while in .NET the standard naming convention is stdcall, which is also the standard for Win32 API calls.

    stdcall and ccall have different name manglings and resposibilities in term of argument cleanup.

    In particular, GHC/GCC will have exported “wEval” while .NET by default would be looking for “_wEval@4”. Now that’s quite easy to fix, just add CallingConvention = CallingConvention.Cdecl.

    But using this calling convention the caller needs to clean up the stack. So you would need extra work. Now assuming you’re only going to use this on Windows, just export your Haskell function as stdcall. This makes your .NET code simpler and makes

    [DllImport("foo.dll", CharSet = CharSet.Unicode)]
    public static extern string myExportedFunction(string in);
    

    almost correct.

    What’s correct would be for example

    [DllImport("foo.dll", CharSet = CharSet.Unicode)]
    public unsafe static extern char* myExportedFunction([MarshalAs(UnmanagedType.LPWStr)]string in);
    

    No more need for loadLibrary or the like. And to get a managed string just use

    String result = new String(myExportedFunction("hello"));
    

    for instance.

    One would think that

    [DllImport("foo.dll", CharSet = CharSet.Unicode)]
    [return : MarshalAs(UnmanagedType.LPWStr)]
    public static extern string myExportedFunction([MarshalAs(UnmanagedType.LPWStr)]string in);
    

    should work too, but It doesn’t since the Marshaller expects the String to have been allocated with CoTaskMemAlloc and will call CoTaskMemFree on it and crash.

    If you want to stay completely in managed land, you could always do

    [DllImport("foo.dll", CharSet = CharSet.Unicode)]
    public static extern IntPtr myExportedFunction([MarshalAs(UnmanagedType.LPWStr)]string in);
    

    and then it can be used as

    string result = Marshal.PtrToStringUni(myExportedFunction("hello"));
    

    Tool is available here http://hackage.haskell.org/package/Hs2lib-0.4.8

    Update : There’s somewhat of a big gotcha that I’ve recently discovered. We have to remember that the String type in .NET is immutable. So when the marshaller sends it to out Haskell code, the CWString we get there is a copy of the original. We have to free this. When GC is performed in C# it won’t affect the the CWString, which is a copy.

    The problem however is that when we free it in the Haskell code we can’t use freeCWString. The pointer was not allocated with C (msvcrt.dll)’s alloc. There are three ways (that I know of) to solve this.

    • use char* in your C# code instead of String when calling a Haskell function. You then have the pointer to free when you call returns, or initialize the pointer using fixed.
    • import CoTaskMemFree in Haskell and free the pointer in Haskell
    • use StringBuilder instead of String. I’m not entirely sure about this one, but the idea is that since StringBuilder is implemented as a native pointer, the Marshaller just passes this pointer to your Haskell code (which can also update it btw). When GC is performed after the call returns, the StringBuilder should be freed.
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have some troubles with Haskell's type system. Situation: Following program is taking list
I want to use some Haskell libraries (e.g. Darcs, Pandoc) from Python, but it
I want to create a haskell interpreter that I can use from C++ on
I want use Haskell higher order function Foldr to calculate the length of a
I want use javascript setInterval function to achieve a box rotate animate effect, I
i want use some data from a website with web service. i have a
Haskell beginner here. I want to pass a type parameter with JSON, and have
I read this: http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns I like the idea, want to use the extension. I
I want to call haskell functions out of C++ and did use the tutorial
Say I want to know if F# has a library function of type ('T

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.