标签: marshalling

我是否需要在非托管代码中删除通过Marshal.PtrToStructure封送的结构?

我有这个C++代码:

extern "C" __declspec(dllexport) VOID AllocateFoo(MY_DATA_STRUCTURE** foo)
{
    *foo = new MY_DATA_STRUCTURE;

    //do stuff to foo
}
Run Code Online (Sandbox Code Playgroud)

然后在C#中我调用函数:

[DllImport("MyDll.dll")]
static extern void AllocateFoo(out IntPtr pMyDataStruct);

...

MyDataStructure GetMyDataStructure()
{
    IntPtr pData;
    ManagedAllocateFooDelegate(out pData);

    MyDataStructure foo = (MyDataStructure)Marshal.PtrToStructure(pData, typeof(MyDataStructure));
    return foo;
}
Run Code Online (Sandbox Code Playgroud)

MyDataStructure是一个结构(非类),对应于MY_DATA_STRUCTURE,并且成员被适当地编组.

所以问题:当MyDataStructure是GC时,我是否需要存储pData然后在非托管代码中再次发布它?MSDN对Marshal.PtrToStructure(IntPtr,Type)说:"将数据从非托管内存块编组到指定类型的新分配托管对象." 在那句话中,"马歇尔"是指"复制"吗?在这种情况下,我需要保留(IntPtr pData),然后将其传递给非托管代码(在MyDataStructure析构函数中),这样我可以做一个C++"删除"?

我已经搜索过,但我找不到足够明确的答案.

.net c# interop marshalling

12
推荐指数
2
解决办法
4638
查看次数

"编组"一词的精确定义

在.NET世界中,编组是指仅通过某个边界或通过线路传输的对象/数据的准备,还是指跨边界或线路的准备和传输.

什么可以组织一个电话意味着什么.它是否仅仅意味着在上下文边界上"转移"调用的包装,还是包含和发送(即调用)调用?

很抱歉是个坚持者......

克拉里

.net marshalling

12
推荐指数
1
解决办法
560
查看次数

编组数据太短

我的应用程序需要在会话中保留大型数据对象.通过解析包含具有3-4个字符串的150个X 20个单元的csv,每个数据对象有3-4个.我的应用程序显示此错误 - "编组数据太短".我试过这个 -

  • 删除旧会话表.
  • 删除会话表的旧迁移.
  • 使用创建新迁移rake db:sessions:create.
  • 手动编辑迁移,更改text: datalongtext: data.
  • 使用运行迁移rake db:migrate.

申请的其他细节 -

在视图"index.html.erb"中 - 有一个链接对控制器中的操作进行ajax调用,该操作解析大型csv文件并从中生成一个对象.此对象存储在会话中.

错误日志

` ArgumentError in Scoring#index

Showing app/views/scoring/index.html.erb where line #4 raised:

marshal data too short

Extracted source (around line #4):

1: 
2: <form id="myForm">
3: 
4:   <%= link_to_remote "get csv file",
5:        :url      => { :action => 'show_static_1' },
6:        :update   => "static_score",
7:        :complete => "$('static_score').update(request.responseText)" %>

Application Trace | Framework Trace …
Run Code Online (Sandbox Code Playgroud)

session ruby-on-rails marshalling

12
推荐指数
4
解决办法
1万
查看次数

C#编组来自C++ DLL的double*?

我有一个带有导出函数的C++ DLL:

extern "C" __declspec(dllexport) double* fft(double* dataReal, double* dataImag)
{
  [...]
}
Run Code Online (Sandbox Code Playgroud)

该函数计算两个双数组(实数和虚数)的FFT,返回单个双数组,实数为虚数组件交错:{Re,Im,Re,Im,...}

我不知道如何在C#中调用此函数.我在做的是:

[DllImport("fft.dll")]
static extern double[] fft(double[] dataReal, double[] dataImag);
Run Code Online (Sandbox Code Playgroud)

当我像这样测试它:

double[] foo = fft(new double[] { 1, 2, 3, 4 }, new double[] { 0, 0, 0, 0 });
Run Code Online (Sandbox Code Playgroud)

我收到MarshalDirectiveException异常:

无法封送"返回值":无效的托管/非托管类型组合.

我假设这是因为C++ double*与C#不完全相同double[],但我不确定如何解决它.有任何想法吗?

编辑:我已经更改了签名,以便我现在传递一些额外的信息:

extern "C" __declspec(dllexport) void fft(double* dataReal, double* dataImag, int length, double* output);
Run Code Online (Sandbox Code Playgroud)

我们总是知道长度output是2倍length

[DllImport("fft.dll")]
static extern void fft(double[] dataReal, double[] dataImag, int length, out double[] …
Run Code Online (Sandbox Code Playgroud)

c# c++ interop marshalling dllimport

12
推荐指数
1
解决办法
1万
查看次数

如何将C#数组传递给C++并将其返回给C#并附加其他项?

我有一个使用C++ DLL的C#项目.(在visual studio 2010中)

我必须将一个int数组从C#代码传递给C++函数,而C++函数将在数组中添加少量元素,当控件返回C#代码时,C#代码也会在同一个数组中添加元素.

最初我在C#代码中声明了一个数组(大小为10000),C++代码能够添​​加元素(因为它只是一个int数组,内存分配是相同的),但问题是我因访问而遇到运行时错误在阵列的一边.

我可以将大小增加到100000,但我不知道C++代码将添加多少元素(即使它只能是1个元素).

那么有两种或其他方式存在共同的数据结构(动态数组)吗?我正在使用Visual Studio 2010.

我想做的事情就像这样.
PS:没有编译代码,这里我使用char数组而不是int数组.

C#代码

[DllImport("example1.dll")]
private static extern int fnCPP (StringBuilder a,int size)
...

private void fnCSHARP(){
    StringBuilder buff = new StringBuilder(10000);
    int size=0;
    size = fnCPP (buff,size);
    int x = someCSHARP_fu();
    for ( int i=size; i < x+size; i++) buff[i]='x';// possibility of run time error
}
Run Code Online (Sandbox Code Playgroud)

C++代码

int fnCPP (char *a,int size){
  int x = someOtherCpp_Function();
  for( int i=size; i < x+size ; i++) a[ i ] = 'x'; //possibility …
Run Code Online (Sandbox Code Playgroud)

c# c++ arrays marshalling

12
推荐指数
1
解决办法
2万
查看次数

逐步完成Visual Studio中的"托管到本机转换"?

在尝试回答这个问题时,我决定在调试器视图中手动逐步完成编组过程.

不幸的是,Visual Studio似乎跳过了所有这些有趣的代码.这是对GetProfilesDirectory(WinAPI函数)的P/Invoke调用:

在此输入图像描述

但是在接到这个电话(F11)后,我发现自己并没有FFF9BFD8; 相反,我在GetProfilesDirectory代码中着陆:

在此输入图像描述

[Managed to Native Transition]堆栈上还有条目,暗示Visual Studio刚刚跳过一大堆代码.

我该如何逐步完成这一过渡?

.net pinvoke native marshalling visual-studio

12
推荐指数
1
解决办法
3814
查看次数

在JAXB编组中使用BigDecimal

我有一个带有JAXB字段注释的REST Web服务.例如,

@XmlAccessorType(XmlAccessType.PROPERTY)
public class MyClass{
  private BigDecimal sum;
  //+ getter and setter
}
Run Code Online (Sandbox Code Playgroud)

如果字段"sum"包含大值,例如1234567890.12345,那么它将编组为1.23456789012345E9如何编写仅用于编组此类的规则?

java rest jaxb marshalling

12
推荐指数
1
解决办法
8151
查看次数

blittable类型的非blittable错误

我有这个结构和这段代码:

[StructLayout(LayoutKind.Sequential, Pack = 8)]
private class xvid_image_t
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public int[] stride;

    // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    // public IntPtr[] plane;
}

public int decore()
{
    xvid_image_t myStruct = new xvid_image_t();
    myStruct.stride = new int[4]; // can be commented out - same result
    GCHandle.Alloc(myStruct, GCHandleType.Pinned);

    // ...
}
Run Code Online (Sandbox Code Playgroud)

当我尝试运行它时,我得到一个ArgumentException说法:

对象包含非原始或非blittable数据

看完这个MSDN页面后

以下复杂类型也是blittable类型:

  • blittable类型的一维数组,例如整数数组.但是,包含blittable类型的可变数组的类型本身不是blittable.

  • 仅包含blittable类型的格式化值类型(如果它们被封送为格式化类型,则为类).有关格式化值类型的详细信息,请参阅值类型的默认编组.

我不明白我做错了什么.我不只是想使用Marshal,而是要理解这一点.

所以我真正想知道的是:

  1. 为什么?
  2. 我该如何解决这个问题?
  3. 您提供的解决方案是否也可以使用结构中的注释行?

我使用的是.Net 4.5,但也需要.Net 2.0的解决方案.

.net c# struct garbage-collection marshalling

12
推荐指数
1
解决办法
6511
查看次数

将Jaxb Pojos序列化为多个或不同的名称空间

请考虑以下代码:

Main.java
====
package com.sample;

import com.sample.entity.Customer;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class Main {    

    public static void main(String[] args) throws JAXBException {
       JAXBContext jc = JAXBContext.newInstance(Customer.class);

       Customer customer = new Customer();
       customer.setId(123);

       Marshaller m = jc.createMarshaller();
       m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
       m.marshal(customer, System.out);    
    }
}


Customer.java
====
package com.sample.entity;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Customer {
    private long id;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }
}

package-info.java
==== …
Run Code Online (Sandbox Code Playgroud)

java xml xsd jaxb marshalling

12
推荐指数
1
解决办法
1016
查看次数

您如何编组 sql.NullString 以便将输出展平以仅给出 go 中的值?

给定一个 go 结构

type Company struct {
    ID   int             `json:"id"`              
    Abn  sql.NullString  `json:"abn,string"`
}
Run Code Online (Sandbox Code Playgroud)

当用这样的东西编组时

company := &Company{}
company.ID = 68
company.Abn = "SomeABN"
result, err := json.Marshal(company)
Run Code Online (Sandbox Code Playgroud)

结果是

{
    "id": "68",
    "abn": {
        "String": "SomeABN",
        "Valid": true
    }
}
Run Code Online (Sandbox Code Playgroud)

想要的结果是

{
    "id": "68",
    "abn": "SomeABN"
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试明确说明 Abn 是一个字符串。

Abn  sql.NullString  `json:"abn,string"`
Run Code Online (Sandbox Code Playgroud)

这并没有改变结果。

您如何编组 sql.NullString 以便将输出展平以仅给出 go 中的值?

编辑

在阅读了/sf/users/577955451//sf/users/67613031/的答案后,我得到了类似的结果

package main

import (
    "database/sql"
    "encoding/json"
    "reflect"
    //"github.com/lib/pq"
)

/*
    https://medium.com/aubergine-solutions/how-i-handled-null-possible-values-from-database-rows-in-golang-521fb0ee267
*/

type NullString sql.NullString …
Run Code Online (Sandbox Code Playgroud)

json marshalling go

12
推荐指数
2
解决办法
6337
查看次数