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

  • SEARCH
  • Home
  • 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 191507
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T16:20:50+00:00 2026-05-11T16:20:50+00:00

** MAJOR UPDATE ** I made a minor mistake but I’m still curious about

  • 0

** MAJOR UPDATE **
I made a minor mistake but I’m still curious about exactly what is happening.

The function I am calling is actually “fooV”, a function with this signature:

foo(const char *, const char *, EnumType, va_list)

This clears up the AccessViolationExceptions I was getting, but doesn’t explain why params parameters work for every other .NET type except for strings that will have to be converted to multibyte ANSI characters. I’m going to get the developer of the DLL to expose the version that actually uses … in the parameter list, any hints for PInvoking if va_list is the parameter?

** old post **

This is related to, but different from a recent question I asked.

I have to use PInvoke to call a C library function that has the following signature:

foo(const char *, const char *, EnumType, ...)

The function configures a resource in a way that varies by StructType; the case I’m interested in configures something that expects the varargs to be a single ANSI multibyte string. I used this PInvoke signature to call the function:

    [DllImport(DllName, CharSet = CharSet.Ansi, EntryPoint = "foo")]
    public static extern int Foo(string s1, string s2, EnumType st1, params string[] s3);

The params string[] seemed odd to me, but previous signatures that called this function were using it for other types such as bool so I followed the pattern.

I wrap this with a friendlier .NET method:

public void Foo(string s1, string s2, string s3)
{
    int error = Dll.Foo(s1, s2, EnumType.Foo, s3);
    // handle errors
}

Recently I changed the signature to include “BestFitMapping = false, ThrowOnUnmappableChar = true” in the DLLImport attribute to comply with FxCop’s suggestions. This is a red herring as I will describe later.

What I expect out of making this change is limited support for Unicode. For example, on a machine with an English code page an exception will be thrown if you pass a string that contains a Japanese character. On a Japanese machine, I’d expect to be able to pass a Japanese string to the function. The English test worked as expected, but the Japanese test throws a System.Runtime.InteropServices.COMException with HRESULT 0x8007007A. This happens even without the BestFitMapping and ThrowOnUnmappableChar settings.

I’ve done a little looking around and saw some sites that suggested you could PInvoke varargs by just specifying normal arguments, so I tried this signature:

[DllImport(DllName, CharSet = CharSet.Ansi, EntryPoint = "foo")]
public static extern int Foo(string s1, string s2, EnumType st1, string s3);

This throws an AccessViolationException when I use it on either the English or Japanese machine.

I cannot use UTF-8 or another Unicode encoding because this C library expects and handles only multibyte ANSI. I have found that specifying CharSet.Unicode for this function works, but I’m worried it’s only by coincidence and not something upon which I should rely. I have thought about converting the string to a byte[] using the system code page, but can’t figure out how to specify I’d like to pass a byte array to the varargs parameter.

What’s going on? On the English machine, English characters work fine and Japanese charactes throw an ArgumentException as expected. On the Japanese machine, English characters work fine and Japanese characters throw the COMException. Is there something wrong with my PInvoke signature? I’ve tried using the MarshalAs attribute to specify a type of LPArray and subtype of LPStr, but this fails in the same way. UnmanagedType.LPStr indicates it is a single-byte ANSI string; is there a way to specify a multibyte ANSI string?

** UPDATE **
Here’s an addition of stuff taking current comments into account.

If I specify a calling convention of CDecl and take normal parameters like this:

[DllImport(DllName, CharSet = CharSet.Ansi, EntryPoint = "foo", CallingConvention = CallingConvention.Cdecl)]
public static extern int Foo(string s1, string s2, EnumType e1, string s3) 

When I use this specification, I get an AccessViolationException. So I tried this:

[DllImport(DllName, CharSet = CharSet.Ansi, EntryPoint = "foo", CallingConvention = CallingConvention.CDecl)]
public static extern int Foo(string s1, string s2, EnumType e1, string s3) 

This works for English and throws the COMException when I use Japanese characters.

The only thing I’ve found that works consistently is this:

[DllImport(DllName, CharSet = CharSet.Ansi, EntryPoint = "foo", BestFitMapping = false, ThrowOnUnmappableChar = true)]
public static extern int Foo(string s1, string s2, EnumType e1, params IntPtr[] s3)

To make this work, I use Marshal.StringToHGlobalAnsi() and pass that pointer. This works for English and Japanese. I’m not comfortable with not understanding why this is the solution, but it works.

  • 1 1 Answer
  • 0 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-11T16:20:50+00:00Added an answer on May 11, 2026 at 4:20 pm

    You probably also need to specify CallingConvention=CallingConvention.Cdecl since a varargs function will use a _cdecl calling convention (the default is Winapi which in turn defaults to StdCall).

    You may need something else, but I’m pretty sure you’ll need at least that.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 124k
  • Answers 124k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Are you running on OS 3.0? I saw the same… May 12, 2026 at 1:19 am
  • Editorial Team
    Editorial Team added an answer It looks like you need to register Apache::Session::Memcached with Apache::Session::Wrapper,… May 12, 2026 at 1:19 am
  • Editorial Team
    Editorial Team added an answer Use DATENAME or DATEPART: SELECT DATENAME(dw,GETDATE()) -- Friday SELECT DATEPART(dw,GETDATE())… May 12, 2026 at 1:19 am

Related Questions

** MAJOR UPDATE ** I made a minor mistake but I'm still curious about
I'd like to get access to the current executing Controller so I can offload
I have previously written user interfaces using .NET and Windows Forms. I'm about to
I was reading about refactoring a large slow SQL Query over here , and
I've previously documented my opinions on Clearcase as a source control system, but unfortunately

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

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.