Luke Wage
Luke Wage

Reputation: 703

C# Decimal to VB6 Currency

I have one C# DLL and one Visual Basic 6 DLL.

In C# there is a field x with data type Decimal. In VB6 there is a field y with data type Currency.

What would be the best way to pass x to y and back?

Currently I convert the fields to Double, but I am not sure if there are rounding implications.

Update 1:

Based on the helpful advice this is what my code looks now:

    public void FromVbToNet(long vb6curr)
    {
        decimal value = vb6curr / 10000;
    }

Problem is, when I try to call this from VB6 via interop, I get a compile error:

"Function or interface marked as restricted, or the function uses an Automation type not supported in Visual Basic"

So how do I declare vb6curr? String, Object, Dynamic?

Update 2:

In case anyone needs this for reference, after further reading I came up with the following solution:

[return: MarshalAs(UnmanagedType.Currency)]
public decimal GetDecimalFromNetDll()
{
    decimal value = ... // Read from database
    return value;
}

public void SetDecimalInNetDll([MarshalAs(UnmanagedType.Currency)] decimal value)
{
    // Save to database
}

I call these from my unmanaged code in VB6 with a Currency parameter and everything seems to work so far.

Upvotes: 7

Views: 3528

Answers (2)

Luke Wage
Luke Wage

Reputation: 703

After some reading I came up with this solution (see also under Update 2).

I had to marshal the Decimal type in .Net to the Currency type in the unmanaged VB6 code and vice versa.

[return: MarshalAs(UnmanagedType.Currency)]
public decimal GetDecimalFromNetDll()
{
    decimal value = ... // Read from database
    return value;
} 

public void SetDecimalInNetDll([MarshalAs(UnmanagedType.Currency)] decimal value)
{
    // Save to database
}

For detailed information see: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshalasattribute%28v=vs.110%29.aspx

Upvotes: 7

David Heffernan
David Heffernan

Reputation: 612824

A VB6 Currency data type is stored as a 64 bit integer, implicitly scaled by 10,000. Armed with that knowledge it is straightforward to convert between that type and .net Decimal.

On the VB6 side you pass the data as Currency. On the C# side you pass it as long. Then on the C# side you scale by 10,000 to convert between your decimal value and the long value.

For example when you have a VB6 Currency value held in a C# long you convert to decimal like this:

long vb6curr = ...;
decimal value = vb6curr / 10000;

In the other direction it would be:

decimal value = ...;
long vb6curr = Convert.ToInt64(value*10000);

Upvotes: 9

Related Questions