Вопрос по c, .net, c#, interop – Советы по использованию библиотеки C из C #

9

Error: User Rate Limit Exceeded

Error: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

int lmdif(int (*fcn)(int, int, double*, double*, int*), 
          int m, int n, double* x, double ftol, double xtol, double gtol, 
          int maxfev, double epsfcn, double factor)

Error: User Rate Limit Exceeded

Why don't you...

- Rewrite in C#? I started, but it's already machine-translated from FORTRAN, and I don't much like coding stuff I can't understand.

- Use Error: User Rate Limit ExceededError: User Rate Limit Exceeded

- Recompile in C++? I'm thinking about it, but it looks like a lot of pain

Error: User Rate Limit Exceeded Totonga
Error: User Rate Limit Exceeded leppie
Error: User Rate Limit ExceededliterallyError: User Rate Limit Exceeded.libError: User Rate Limit Exceeded Benjol
Error: User Rate Limit Exceeded Totonga
Error: User Rate Limit Exceeded Prof. Falken

Ваш Ответ

6   ответов
3

  public static unsafe class WrapCDll {
    private const string DllName = "c_functions.dll";

    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
    public static extern void do_stuff_in_c(byte* arg);
  }

Error: User Rate Limit ExceededstdcallError: User Rate Limit Exceededcdecl.
3

Marshalling arrays

double*double*double

[DllImport(@"PathToDll")]
public static extern Foo(
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)[In] double[] x, 
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)[Out] double[] y, 
    int x_size, 
    int y_size)

SizeParamIndex

xinto Fooy.

Calling convention

StdCallCdecl

CC#StdCallCdecl

//=======C-code======
//type signature of callback function
typedef int (__stdcall *FuncCallBack)(int, int);

void SetWrappedCallback(FuncCallBack); //here default = __cdecl

//======C# code======
public delegate int FuncCallBack(int a, int b);   // here default = StdCall 

[DllImport(@"PathToDll", CallingConvention = CallingConvention.Cdecl)]
private static extern void SetWrappedCallback(FuncCallBack func);
Packaging the callback

int MyFunc(int a, int b)
{
   return a * b;
}
//...

FuncCallBack ptr = new FuncCallBack(MyFunc);
SetWrappedCallback(ptr);
.def file

DllImportModDef.def

LIBRARY MyLibName
EXPORTS
    SetWrappedCallback  @1
extern "C"

extern "C"

extern "C" {
  #include "C_declarations.h"
}
Precompiled headers

Right-click -> Properties -> C/C++ -> Precompiled HeadersPrecompiled headerNot Using Precompiled Headers

1

Error: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceeded. This little tool is still useful to marshall C interfaces. Copy and past interface code into the "SigImp Translation Sniplet" and watch the results.

Error: User Rate Limit Exceeded

/// Return Type: int
///param0: int
///param1: int
///param2: double*
///param3: double*
///param4: int*
public delegate int Anonymous_83fd32fd_91ee_45ce_b7e9_b7d886d2eb38(int param0, int param1, ref double param2, ref double param3, ref int param4);

public partial class NativeMethods {

    /// Return Type: int
    ///fcn: Anonymous_83fd32fd_91ee_45ce_b7e9_b7d886d2eb38
    ///m: int
    ///n: int
    ///x: double*
    ///ftol: double
    ///xtol: double
    ///gtol: double
    ///maxfev: int
    ///epsfcn: double
    ///factor: double
    [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="lmdif", CallingConvention=System.Runtime.InteropServices.CallingConvention.Cdecl)]
public static extern  int lmdif(Anonymous_83fd32fd_91ee_45ce_b7e9_b7d886d2eb38 fcn, int m, int n, ref double x, double ftol, double xtol, double gtol, int maxfev, double epsfcn, double factor) ;

}
3

stdcallcdeclReflection.Emit).

Reflection.EmitInvoke

Error: User Rate Limit Exceeded
3

:

"Converts a delegate into a function pointer that is callable from unmanaged code."

1

class Program
    {  
        [DllImport("namEm.DLL", CallingConvention = CallingConvention.Cdecl, EntryPoint = "nameEm", 
            CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
        public static extern int nameEm([MarshalAs(UnmanagedType.LPStr)] StringBuilder str);
        static void Main(string[] args)
        {
            int m = 3;
            StringBuilder str = new StringBuilder();
            str.Append(String.Format("{0};", m));
            str.Append(String.Format("{0} {1:E4};", 5, 76.334E-3 ));
            str.Append(String.Format("{0} {1} {2} {3};", 65,45,23,12));
            m = nameEm(str);
        }
    }

extern "C"
{
    __declspec(dllexport) int __cdecl nameEm(char* names)
    {
        int n1, n2, n3[4];
        char *token,
             *next_token2 = NULL,
             *next_token = NULL;
        float f;

        sscanf_s(strtok_s(names, ";", &next_token), "%d", &n2);
        sscanf_s(strtok_s(NULL, ";", &next_token), "%d %f", &n1, &f);
        // Observe the use of two different strtok-delimiters.
        // the ';' to pick the sequence of 4 integers,
        // and the space to split that same sequence into 4 integers.
        token = strtok_s(strtok_s(NULL, ";", &next_token)," ",&next_token2);
        for (int i=0; i < 4; i++)
        {
             sscanf_s(token,"%d", &n3[i]);
             token = strtok_s(NULL, " ",&next_token2);
        }    
        return 0;
    }
}

Похожие вопросы