Arduino स्केच से C फ़ंक्शन को कैसे कॉल करें?


10

मैं जानना चाहूंगा कि क्या अरडिनो स्केच का उपयोग करके सी फाइलों के भीतर निहित फ़ंक्शन को कॉल करने का एक तरीका है?

मेरी सी फ़ाइल एक फ़ंक्शन को घोषित और परिभाषित करती है। अपने Arduino स्केच में गन्दा फंक्शन डेफिनिशन डालने से बचाने के लिए, मैं स्कैच से सीधे फंक्शन को कॉल करना चाहूँगा।

क्या Arduino और C का उपयोग करने का एक मानक तरीका है? यहाँ स्केच है:

#include "crc16.h";

void setup(){

}

void loop(){

  CalculateCRC16("<09M", 4);

}

और यह C फ़ाइल को छाँटा गया है:

#include <stdio.h>
#include <stdint.h>

uint16_t crctable[256] =
{
    0x0000, 0x1189,.....



uint16_t // Returns Calculated CRC value
CalculateCRC16( // Call example CalculateCRC16("<09M", 4);
    const void *c_ptr, // Pointer to byte array to perform CRC on
    size_t len)        // Number of bytes to CRC
{

    uint16_t crc = 0xFFFF // Seed for CRC calculation
    const uint8_t *c = c_ptr;

    while (len--)
        crc = (crc << 8) ^ crctable[((crc >> 8) ^ *c++)];

    return crc;
}

क्या कोई कारण है कि आपकी फ़ाइल को C ++ के बजाय C का उपयोग करना है?
पीटर ब्लूमफील्ड

वास्तव में हाँ। जब मैं C ++ का उपयोग करके फ़ाइल संकलित करने का प्रयास करता हूं, तो त्रुटियां होती हैं, लेकिन यह C. में त्रुटि मुक्त है। त्रुटि लाइनों के कारण होती है: const void *c_ptrऔर const uint8_t *c = c_ptr;। त्रुटि संदेश प्रकारों के बीच एक अमान्य रूपांतरण का उल्लेख करता है।
user_name

4
क्या आप 2 कोड फ़ाइलों (या उनमें से एक सरलीकृत न्यूनतम संस्करण) को पोस्ट कर सकते हैं जो त्रुटि उत्पन्न करते हैं, और त्रुटि संदेश को पूर्ण रूप से कॉपी और पेस्ट करते हैं?
द्रोड़ी

त्रुटि संदेश बहुत सुंदर नहीं हैं: In function uint16_t CalculateCRC16(uint16_t, const void*, size_t)': 46 invalid conversion from const v * * toconst uint8_t*' In function int main()': 57 system' undeclared (first use this function) (Each undeclared identifier is reported only once for each function it appears in.)
user_name

जवाबों:


10

आप निम्न की तरह "C" # साइन आउट कर सकते हैं:

extern "C"{
#include "crc16.h"
};

void setup(){
}

void loop(){
  CalculateCRC16("<09M", 4);
}

और crc16.h फ़ाइल हो सकती है (कुछ मामूली सुधार, #pragma एक बार, एक डाली):

#pragma once

#include <stdio.h>
#include <stdint.h>

uint16_t crctable[2] ={ 0x0000, 0x1189};

uint16_t CalculateCRC16( // Call example CalculateCRC16("<09M", 4);
    const void *c_ptr, // Pointer to byte array to perform CRC on
    size_t len)        // Number of bytes to CRC
{
    uint16_t crc = 0xFFFF; // Seed for CRC calculation
    const uint8_t *c = (const uint8_t *)c_ptr;

    while (len--)
        crc = (crc << 8) ^ crctable[((crc >> 8) ^ *c++)];

    return crc;
}

धन्यवाद, यह अब ठीक काम करता है। क्या आप प्रज्ञा की आवश्यकता समझा सकते हैं?
user_name

1
यकीन है, यह एक अच्छा अभ्यास है, हालांकि यह आपके उदाहरण में आवश्यक नहीं है। यह एक ही हेडर फ़ाइल को एक संकलन फ़ाइल में दो बार शामिल करने से बचता है। A.cpp की कल्पना करें -> (bh और ch) और bh-> ch जो a.cpp को संकलित करते समय ch की सामग्रियों की नकल करेगा। # प्रपमा एक बार इससे बच जाता है। साथ ही गार्ड के निर्देश #ifndef _MY_FILE_H_INCLUDED #define _MY_FILE_H_INCLUDED इसके लिए सामान्य हैं। ध्यान दें, हालांकि, जैसा कि पीटर आर। ब्लूमफील्ड बताते हैं, यह एक सीपीपी फ़ाइल में कैलकुलेटसीआर 16 के कार्यान्वयन को लागू करने के लिए बेहतर हो सकता है, और हेडर फ़ाइल में केवल घोषणा को छोड़ दें।
द्रोड़ी

ठीक है, मैं देख सकता हूं कि जब कोड अधिक से अधिक जटिल हो जाता है तो यह एक मुद्दा बन जाता है। सलाह के लिए धन्यवाद।
user_name

4

आपका CRC फ़ंक्शन आसानी से C ++ में परिवर्तित हो सकता है ताकि यह एक * .cpp फ़ाइल में जा सके। जब आप अपने cसूचक को इनिशियलाइज़ करते हैं, तो आपको एक स्पष्ट कास्ट का उपयोग करने की आवश्यकता होती है । यहां 'उचित' C ++ करने का तरीका दिया गया है:

const uint8_t *c = static_cast<const uint8_t*>(c_ptr);

हालांकि, एक पुरानी सी-स्टाइल कास्ट भी काम करेगा:

const uint8_t *c = (const uint8_t*)c_ptr;

समस्या मूल रूप से यह है कि सी आपको कुछ प्रकार के बीच संकेत देने वाले बिंदुओं को बदलने की अनुमति देने के बारे में थोड़ा अधिक अनुमति दे सकता है। सी ++ में करने के लिए, आपको संकलक को स्पष्ट रूप से बताने की आवश्यकता है कि रूपांतरण जानबूझकर किया गया है।


1

हां, अपने स्केच में इसकी घोषणा लाइन को कॉपी करें:

extern "C" {
    void myfunction(int arg);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.