2016-08-25 13 views
9

Tôi biết điều này đã được hỏi trước, nhưng tôi không thành công khi cố chuyển đổi một số cấu trúc/công đoàn C++ sang Delphi để sử dụng SDK Hikvision.Làm thế nào để chuyển đổi một liên minh C++ sang Delphi

C++ cấu trúc/đoàn thể tôi đang cố gắng để chuyển đổi như sau:

struct{ 
    BYTE       byEnable; 
    BYTE       byRes1[3]; 
    DWORD       dwTriggerType; 
    NET_ITC_TRIGGER_PARAM_UNION uTriggerParam; 
    BYTE       byRes[64]; 
}NET_ITC_SINGLE_TRIGGERCFG,*LPNET_ITC_SINGLE_TRIGGERCFG; 

union{ 
    DWORD        uLen[1070]; 
    NET_ITC_POST_IOSPEED_PARAM   struIOSpeed; 
    NET_ITC_POST_SINGLEIO_PARAM  struSingleIO; 
    NET_ITC_POST_RS485_PARAM   struPostRs485; 
    NET_ITC_POST_RS485_RADAR_PARAM  struPostRadar; 
    NET_ITC_POST_VTCOIL_PARAM   struVtCoil; 
    NET_ITC_EPOLICE_IOTL_PARAM   struIOTL; 
    NET_ITC_EPOLICE_RS485_PARAM  struEpoliceRs485; 
    NET_ITC_EPOLICE_RS485_PARAM  struPERs485; 
}NET_ITC_TRIGGER_PARAM_UNION,*LPNET_ITC_TRIGGER_PARAM_UNION; 

Tôi đã thử những điều sau đây:

PNetItcSingleTriggerCfg = ^TNetItcSingleTriggerCfg; 
    TNetItcSingleTriggerCfg = record 
    byEnable:  Byte; 
    byRes1:  array [0..2] of Byte; 
    dwTriggerType: DWord; 
    uTriggerParam: TNetItcTriggerParamUnion; 
    byRes:   array [0..63] of Byte; 
    end; 

    PNetItcTriggerParamUnion = ^TNetItcTriggerParamUnion; 
    TNetItcTriggerParamUnion = record 
    case integer of 
     0: (uLen:    array [0..1069] of DWord); 
     1: (struIOSpeed:  TNetItcPostIOSpeedParam); 
     2: (struSingleIO:  TNetItcPostSingleIOParam); 
     3: (struPostRs485: TNetItcPostRS485Param); 
     4: (struPostRadar: TNetItcPostRS485RadarParam); 
     5: (struVtCoil:  TNetItcPostVTCoilParam); 
     6: (struHvt:   TNetItcPostHvtParam); 
     7: (struIOTL:   TNetItcEPoliceIOTLParam); 
     8: (struEpoliceRs485: TNetItcEPoliceRS485Param); 
     9: (struPERs485:  TNetItcEPoliceRS485Param);   
     10:(struPostMpr:  TNetItcPostMprParam); 
     11:(struViaVtCoil: TNetDvrViaVtCoilParam); 
     12:(struPostImt:  TNetItcPostImtParam); 
     13:(struPostPrs:  TNetItcPostPrsParam); 
     14:(struIpcHvt:  TNetIpcPostHvtParam); 
     15:(struHvtV50:  TNetIpcPostHvtParamV50); 
    end; 

Và tôi cũng đã cố gắng có nó như một kỷ lục lồng nhau (như được đề xuất ở đây http://rvelthuis.de/articles/articles-convert.html#unions)

PNetItcSingleTriggerCfg = ^TNetItcSingleTriggerCfg; 
    TNetItcSingleTriggerCfg = record 
    byEnable:  Byte; 
    byRes1:  array [0..2] of Byte; 
    dwTriggerType: DWord; 
    uTriggerParam: record 
     case integer of 
     0: (uLen:    array [0..1069] of DWord); 
     1: (struIOSpeed:  TNetItcPostIOSpeedParam); 
     2: (struSingleIO:  TNetItcPostSingleIOParam); 
     3: (struPostRs485: TNetItcPostRS485Param); 
     4: (struPostRadar: TNetItcPostRS485RadarParam); 
     5: (struVtCoil:  TNetItcPostVTCoilParam); 
     6: (struHvt:   TNetItcPostHvtParam); 
     7: (struIOTL:   TNetItcSingleIOTLParam); 
     8: (struEpoliceRs485: TNetItcEPoliceRS485Param); 
     9: (struPERs485:  TNetItcEPoliceRS485Param); 
     10:(struPostMpr:  TNetItcPostMprParam); 
     11:(struViaVtCoil: TNetDvrViaVtCoilParam); 
     12:(struPostImt:  TNetItcPostImtParam); 
     13:(struPostPrs:  TNetItcPostPrsParam); 
     14:(struIpcHvt:  TNetIpcPostHvtParam); 
     15:(struHvtV50:  TNetIpcPostHvtParamV50); 
     end; 
    byRes:   array [0..63] of Byte; 
    end; 

Tôi đã thấy các câu hỏi tương tự ở đây (I E. How do I translate a C union into Delphi?), nhưng công đoàn trong ví dụ của tôi là ở giữa của cấu trúc, và như tôi hiểu 'kết thúc' của tuyên bố trường hợp cũng kết thúc kỷ lục. Tôi nghĩ rằng tôi hiểu lý thuyết đằng sau một bản ghi biến thể có cùng một cấp phát bộ nhớ cho các trường trong câu lệnh case, do đó, các trường được sử dụng sẽ là/hoặc, nhưng những gì tôi không thể làm ra là cách nói DLL đang truy cập vào các bản ghi này, cho dù đó là struName.unionName.fieldName hoặc struName.fieldName và cũng làm thế nào công đoàn được định nghĩa (nghĩa là bộ chọn của câu lệnh case là gì, và làm thế nào để biết kiểu dữ liệu nào mà bộ chọn là).

Tôi có ba cấu trúc tương tự để dịch và hình dung nếu tôi có thể bẻ khóa một, tôi có thể bẻ khóa tất cả.

Với các bản ghi như được mô tả ở trên, tôi tiếp tục nhận được thông báo lỗi 'Lỗi tham số. Tham số đầu vào hoặc đầu ra trong SDK SDK là NULL trong khi gọi một hàm từ tệp DLL (nếu bạn cần thêm thông tin về điều này, vui lòng hỏi), điều này khiến tôi nghĩ rằng bản ghi của tôi chưa được chuyển đổi chính xác.

Tôi đang sử dụng phiên bản SDK HCNetSDK.dll 5.0.3.20 và IDE của tôi là XE7 nếu điều đó giúp.

Mọi trợ giúp sẽ được đánh giá cao.

+2

FWIW, nhiều hơn về chuyển đổi hồ sơ và công đoàn ở đây: http://rvelthuis.de/articles/articles-convert.html#unions Nhưng như @DavidHeffernan đã nói, chuyển đổi của bạn là OK, nhưng sự liên kết có thể bị tắt. Có một phần về sự liên kết trong bài viết đó. –

+0

Đây thực sự là một bản dupe. https://stackoverflow.com/search?q=%5Bdelphi%5D+union –

+0

Không thực sự là lừa đảo. Người hỏi đã thực hiện nghiên cứu tốt và muốn biết tại sao mã kết quả dường như không hoạt động như mong đợi. –

Trả lời

6

Giả sử rằng cài đặt căn chỉnh cấu trúc khớp nhau thì cả hai lần thử chuyển đổi công đoàn đều chính xác. Bạn có thể sử dụng cái nào bạn thích. Đối với những gì nó có giá trị, tôi sẽ thích cách tiếp cận đầu tiên, nơi bạn tuyên bố một loại để đại diện cho công đoàn.

Bất kể vấn đề thực tế của bạn là gì, nó dường như không nói dối với chuyển đổi công đoàn. Một cách đơn giản để kiểm tra điều này là kiểm tra xem kích thước của các loại có khớp với các phiên bản C++ và Delphi hay không, và số bù cho mỗi thành viên phù hợp.

Để kiểm tra kích thước của loại sử dụng sizeof trong C++ và SizeOf ở Delphi. Để bù đắp, sử dụng macro offsetof cho C++ và mẹo được hiển thị trong my answer here cho Delphi.

+0

Trên thực tế, suy nghĩ về nó: một chuyển đổi thích hợp của một công đoàn có lẽ nên sử dụng một hồ sơ đóng gói. AFAIK, tiêu chuẩn C làm cho nó bắt buộc rằng tất cả các yếu tố được liên kết tại cùng một địa chỉ, nhưng không có tiêu chuẩn Delphi và tôi không biết nếu đó là đúng cho tất cả các trình biên dịch hiện đang được sử dụng.Gói được lưu trữ đảm bảo rằng tất cả các phần được căn chỉnh tại cùng một địa chỉ. –

+2

@RudyVelthuis Chúng tôi đã có cuộc thảo luận này rất nhiều lần trước đây. Lực đóng gói bản ghi được căn chỉnh. Điều đó sẽ không ảnh hưởng đến bố cục bởi vì một bản ghi biến thể luôn đặt các thành viên biến thể ở cùng độ lệch. Nhưng nó sẽ dẫn đến sự lệch hướng của cấu trúc. Ví dụ một công đoàn có chứa một int và một double có kích thước 8, và căn chỉnh 8. Khi căn chỉnh nó luôn luôn nên được đặt trên 8 byte ranh giới. Nếu bạn gói nó thì điều đó sẽ không xảy ra. Nếu mã C++ buộc công đoàn phải căn chỉnh 1, sau đó đóng gói nó, nếu không thì không. –

+0

@David Cảm ơn bạn đã dành thời gian trả lời câu hỏi của tôi. Ít nhất bây giờ tôi có thể tìm nơi khác để xem nơi mà lỗi của tôi nằm. Vậy cái gì định nghĩa bộ chọn của công đoàn? –

Các vấn đề liên quan