Lymphatus / libcaesium

The Caesium compression library written in Rust (with a C interface)
Apache License 2.0
128 stars 23 forks source link

How to use caesium.dll in C# #17

Closed handloong closed 11 months ago

handloong commented 11 months ago

I wrote the following code using C #, but i got an error :Invalid jpeg quality value

I am a beginner in Rust, and I only write some log in Rust Code, like this:

 #[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn c_compress(
    input_path: *const c_char,
    output_path: *const c_char,
    params: CCSParameters,
) -> CCSResult {
    let parameters = c_set_parameters(params);
    println!("input_path value:{}",CStr::from_ptr(input_path).to_str().unwrap().to_string()); 
    println!("output_path value:{}",CStr::from_ptr(output_path).to_str().unwrap().to_string()); 
...
}

fn c_set_parameters(params: CCSParameters) -> CSParameters {
    let mut parameters = initialize_parameters();
    println!("initialize_parameters parameters.jpeg.quality value:{}",parameters.jpeg.quality); 
    println!("params.jpeg_quality value:{}",params.jpeg_quality); 
...

and release to compile caesium.dll

(My computer is 64 bit , and c sharp code is also 64 bit and caesium.dll also 64bit.)

C sharp code run in .Net Framework 4.8

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace sharpTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var input_path = @"C:\Users\Administrator\Desktop\Test\1830.jpg"; // this file exist
            var output_path = @"C:\Users\Administrator\Desktop\Test\1830_saved.jpg"; // this file not exist

            var bytesInput = Encoding.UTF8.GetBytes(input_path);
            var bytesOutput = Encoding.UTF8.GetBytes(output_path);

            uint quality = 50;
            var paramater = new CCSParameters
            {
                jpeg_quality = quality,
                gif_quality = quality,
                png_quality = quality,
                webp_quality = quality,
                keep_metadata = false,
                jpeg_chroma_subsampling = quality,
                optimize = true,
                png_force_zopfli = false,
                //height = 300,
                //width = 500,
            };

            var resultPrt = c_compress(bytesInput, bytesOutput, paramater, out CCSResult realResult);
            if (realResult.success)
            {
                Console.WriteLine("ok");
            }
            else
            {
                CCSResult result = Marshal.PtrToStructure<CCSResult>(resultPrt);
                var errorMessage = Marshal.PtrToStringAnsi(result.error_message);
                Console.WriteLine(errorMessage);
            }
        }

        [DllImport("caesium.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true, EntryPoint = "c_sharp_compress")]
        public static extern IntPtr c_sharp_compress(
           byte[] input_path,
           out CCSResult result
        );

        [DllImport("caesium.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "c_compress")]
        public static extern IntPtr c_compress(
           byte[] input_path,
           byte[] output_path,
           CCSParameters parameters,
           out CCSResult result
        );

        [StructLayout(LayoutKind.Sequential)]
        public struct CCSParameters
        {
            public bool keep_metadata;
            public uint jpeg_quality;
            public uint jpeg_chroma_subsampling;
            public uint png_quality;
            public bool png_force_zopfli;
            public uint gif_quality;
            public uint webp_quality;
            public bool optimize;
            public uint width;
            public uint height;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct CCSResult
        {
            public bool success;
            public IntPtr error_message;
        }
    }
}

Terminal output:

image Input Path and output The path seems to be reversed ?

Could you help me how to solve this problem ? or Could you write a C # demo , Thanks